    <?php
    /**
     * Plugin Name: WordPress Spider Monitor
     * Plugin URI: https://zibovip.top
     * Description: 由Eric开发的专业WordPress蜘蛛访问监控插件，实时监控百度、谷歌、必应、360、搜狗等主流搜索引擎蜘蛛的访问情况，提供详细的访问统计、分析报告和URL自动推送功能。支持多搜索引擎URL推送，提升网站收录效率。
     * Version: 2.0.0
     * Author: Eric
     * Author URI: https://zibovip.top
     * License: GPL v2 or later
     * Text Domain: wp-spider-monitor
     */

    // 防止直接访问
    if (!defined('ABSPATH')) {
        exit;
    }

    // 定义插件常量（避免重复定义导致 Warning）
    if (!defined('WP_SPIDER_MONITOR_VERSION')) {
        define('WP_SPIDER_MONITOR_VERSION', '2.0.0');
    }
    if (!defined('WP_SPIDER_MONITOR_PLUGIN_URL')) {
        define('WP_SPIDER_MONITOR_PLUGIN_URL', plugin_dir_url(__FILE__));
    }
    if (!defined('WP_SPIDER_MONITOR_PLUGIN_PATH')) {
        define('WP_SPIDER_MONITOR_PLUGIN_PATH', plugin_dir_path(__FILE__));
    }

    // 数据库表名常量
    global $wpdb;
    if (!defined('WP_SPIDER_MONITOR_VISITS_TABLE')) {
        define('WP_SPIDER_MONITOR_VISITS_TABLE', $wpdb->prefix . 'spider_visits');
    }
    if (!defined('WP_SPIDER_MONITOR_STATS_TABLE')) {
        define('WP_SPIDER_MONITOR_STATS_TABLE', $wpdb->prefix . 'spider_stats');
    }
    if (!defined('WP_SPIDER_MONITOR_PUSH_URLS_TABLE')) {
        define('WP_SPIDER_MONITOR_PUSH_URLS_TABLE', $wpdb->prefix . 'spider_push_urls');
    }
    if (!defined('WP_SPIDER_MONITOR_PUSH_CONFIG_TABLE')) {
        define('WP_SPIDER_MONITOR_PUSH_CONFIG_TABLE', $wpdb->prefix . 'spider_push_config');
    }
    if (!defined('WP_SPIDER_MONITOR_PUSH_LOG_TABLE')) {
        define('WP_SPIDER_MONITOR_PUSH_LOG_TABLE', $wpdb->prefix . 'spider_push_log');
    }

    // 搜索引擎配置常量
    if (!defined('WP_SPIDER_MONITOR_BAIDU_API')) {
        define('WP_SPIDER_MONITOR_BAIDU_API', 'http://data.zz.baidu.com/urls');
    }
    if (!defined('WP_SPIDER_MONITOR_BING_API')) {
        define('WP_SPIDER_MONITOR_BING_API', 'https://ssl.bing.com/webmaster/api.svc/json/SubmitUrlBatch');
    }
    if (!defined('WP_SPIDER_MONITOR_GOOGLE_API')) {
        define('WP_SPIDER_MONITOR_GOOGLE_API', 'https://indexing.googleapis.com/v3/urlNotifications:publish');
    }
    if (!defined('WP_SPIDER_MONITOR_360_API')) {
        define('WP_SPIDER_MONITOR_360_API', 'http://info.so.com/urls');
    }
    if (!defined('WP_SPIDER_MONITOR_SOGOU_API')) {
        define('WP_SPIDER_MONITOR_SOGOU_API', 'http://fankui.help.sogou.com/index.php/web/web/addShouLu');
    }

    // 作者信息常量
    if (!defined('WP_SPIDER_MONITOR_AUTHOR')) {
        define('WP_SPIDER_MONITOR_AUTHOR', 'Eric');
    }
    if (!defined('WP_SPIDER_MONITOR_AUTHOR_URL')) {
        define('WP_SPIDER_MONITOR_AUTHOR_URL', 'https://zibovip.top');
    }
    if (!defined('WP_SPIDER_MONITOR_SITE_URL')) {
        define('WP_SPIDER_MONITOR_SITE_URL', 'https://zibovip.top');
    }

    // 预加载安全模块，避免在早期调用时报未定义
    if (file_exists(plugin_dir_path(__FILE__) . 'includes/premium-security.php')) {
        require_once plugin_dir_path(__FILE__) . 'includes/premium-security.php';
    }
    if (file_exists(plugin_dir_path(__FILE__) . 'includes/secure-license-verification.php')) {
        require_once plugin_dir_path(__FILE__) . 'includes/secure-license-verification.php';
    }

    // 主插件类
    class WP_Spider_Monitor {
        
        public function __construct() {
            // 立即检查并创建数据库表
            $this->check_and_create_tables();
            // 升级数据库结构（如新增精准蜘蛛字段）
            $this->ensure_schema_upgrades();
            
            // 新的付费验证系统
            require_once plugin_dir_path(__FILE__) . 'subscription-client.php';
            
            // 引入安全验证模块（存在才引入，避免因缺失导致致命错误）
            $sec_file = plugin_dir_path(__FILE__) . 'includes/premium-security.php';
            if (file_exists($sec_file)) { require_once $sec_file; }
            $ver_file = plugin_dir_path(__FILE__) . 'includes/secure-license-verification.php';
            if (file_exists($ver_file)) { require_once $ver_file; }
            
            add_action('init', array($this, 'init'));
            add_action('admin_menu', array($this, 'add_admin_menu'));
            add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'));
            // 统一菜单激活高亮
            add_filter('parent_file', array($this, 'filter_parent_file'));
            add_filter('submenu_file', array($this, 'filter_submenu_file'));
            
            // 蜘蛛监控相关AJAX
            add_action('wp_ajax_spider_get_daily_stats', array($this, 'ajax_get_daily_stats'));
            add_action('wp_ajax_spider_get_spider_details', array($this, 'ajax_get_spider_details'));
            add_action('wp_ajax_spider_get_spider_urls', array($this, 'ajax_get_spider_urls'));
            add_action('wp_ajax_spider_export_stats', array($this, 'ajax_export_stats'));
            add_action('wp_ajax_spider_clear_old_visits', array($this, 'ajax_clear_old_visits'));
            add_action('wp_ajax_spider_create_tables', array($this, 'ajax_create_tables'));
            add_action('wp_ajax_spider_get_today_stats', array($this, 'ajax_get_spider_today_stats'));
            // 记录管理 - 规则设置
            add_action('wp_ajax_spider_set_rule', array($this, 'ajax_spider_set_rule'));
            
            // 收录分析相关AJAX
            add_action('wp_ajax_spider_check_indexing', array($this, 'ajax_check_indexing_status'));
            // 新增：第三方优先的检测（避免与旧实现冲突）
            add_action('wp_ajax_spider_check_indexing_status', array($this, 'ajax_check_indexing_status_v2'));
            add_action('wp_ajax_spider_get_indexing_list', array($this, 'ajax_get_indexing_list'));
            
            // 蜘蛛概况相关AJAX
            add_action('wp_ajax_spider_get_overview_stats', array($this, 'ajax_get_overview_stats'));
            add_action('wp_ajax_spider_get_trend_data', array($this, 'ajax_get_trend_data'));
            
            // SPA页面AJAX处理
            add_action('wp_ajax_spider_get_overview_page', array($this, 'ajax_get_overview_page'));
            add_action('wp_ajax_spider_get_logs_page', array($this, 'ajax_get_logs_page'));
            add_action('wp_ajax_spider_get_list_page', array($this, 'ajax_get_list_page'));
            add_action('wp_ajax_spider_get_paths_page', array($this, 'ajax_get_paths_page'));
            add_action('wp_ajax_spider_get_articles_page', array($this, 'ajax_get_articles_page'));
            add_action('wp_ajax_spider_get_indexing_page', array($this, 'ajax_get_indexing_page'));
            add_action('wp_ajax_spider_get_push_page', array($this, 'ajax_get_push_page'));
            add_action('wp_ajax_spider_get_settings_page', array($this, 'ajax_get_settings_page'));
            add_action('wp_ajax_spider_get_plugin_settings_page', array($this, 'ajax_get_plugin_settings_page'));
            add_action('wp_ajax_spider_get_settings_tab', array($this, 'ajax_get_settings_tab'));
            add_action('wp_ajax_spider_get_license_page', array($this, 'ajax_get_license_page'));
            add_action('wp_ajax_spider_get_top_spiders', array($this, 'ajax_get_top_spiders'));
            add_action('wp_ajax_spider_get_top_urls', array($this, 'ajax_get_top_urls'));
            add_action('wp_ajax_spider_get_top_articles', array($this, 'ajax_get_top_articles'));
            
            // 蜘蛛列表相关AJAX
            add_action('wp_ajax_spider_get_spider_list', array($this, 'ajax_get_spider_list'));
            add_action('wp_ajax_spider_get_fake_spiders', array($this, 'ajax_get_fake_spiders'));
            add_action('wp_ajax_spider_get_block_rules', array($this, 'ajax_get_block_rules'));
            add_action('wp_ajax_spider_add_block_rule', array($this, 'ajax_add_block_rule'));
            add_action('wp_ajax_spider_remove_block_rule', array($this, 'ajax_remove_block_rule'));
            
            // 访问路径相关AJAX
            add_action('wp_ajax_spider_get_access_paths', array($this, 'ajax_get_access_paths'));
            add_action('wp_ajax_spider_get_url_type_stats', array($this, 'ajax_get_url_type_stats'));
            
            // 文章爬取相关AJAX
            add_action('wp_ajax_spider_get_article_crawl', array($this, 'ajax_get_article_crawl'));
            add_action('wp_ajax_spider_get_article_stats', array($this, 'ajax_get_article_stats'));
            
            // 安全验证AJAX处理
            add_action('wp_ajax_wp_spider_validate_premium_access', array($this, 'ajax_validate_premium_access'));
            add_action('wp_ajax_wp_spider_verify_token', array($this, 'ajax_verify_token'));
            add_action('wp_ajax_spider_get_crawl_trend', array($this, 'ajax_get_crawl_trend'));
            
            // 访问路径相关AJAX
            add_action('wp_ajax_spider_get_path_stats', array($this, 'ajax_get_path_stats'));
            
            // 蜘蛛列表管理相关AJAX
            add_action('wp_ajax_spider_get_ip_segments', array($this, 'ajax_get_ip_segments'));
            add_action('wp_ajax_spider_bulk_action', array($this, 'ajax_bulk_action'));
            add_action('wp_ajax_spider_toggle_status', array($this, 'ajax_toggle_spider_status'));
            add_action('wp_ajax_spider_block_ip_segment', array($this, 'ajax_block_ip_segment'));
            add_action('wp_ajax_spider_block_fake_spider', array($this, 'ajax_block_fake_spider'));
            add_action('wp_ajax_spider_toggle_rule_status', array($this, 'ajax_toggle_rule_status'));
            add_action('wp_ajax_spider_delete_rule', array($this, 'ajax_delete_rule'));
            
            // 付费版接口
            add_action('wp_ajax_spider_check_premium', array($this, 'ajax_check_premium'));
            add_action('wp_ajax_spider_upgrade_premium', array($this, 'ajax_upgrade_premium'));
            add_action('wp_ajax_spider_diagnose_activation', array($this, 'ajax_diagnose_activation'));
            add_action('wp_ajax_spider_fix_activation', array($this, 'ajax_fix_activation'));
            
            // 初始化付费版过滤器
            add_filter('wp_spider_monitor_is_premium', array($this, 'is_premium_version'));
            
            // 主题相关AJAX
            add_action('wp_ajax_save_theme_preference', array($this, 'ajax_save_theme_preference'));
            add_action('wp_ajax_get_theme_preview', array($this, 'ajax_get_theme_preview'));
            add_action('wp_ajax_get_user_theme', array($this, 'ajax_get_user_theme'));
            
            // AJAX处理函数
            add_action('wp_ajax_create_spider_tables', array($this, 'ajax_create_spider_tables'));
            add_action('wp_ajax_export_spider_data', array($this, 'ajax_export_spider_data'));
            add_action('wp_ajax_clear_spider_data', array($this, 'ajax_clear_spider_data'));
            add_action('wp_ajax_test_insert', array($this, 'ajax_test_insert'));
            
            // URL推送相关AJAX
            add_action('wp_ajax_save_push_config', array($this, 'ajax_save_push_config'));
            add_action('wp_ajax_test_push_connection', array($this, 'ajax_test_push_connection'));
            add_action('wp_ajax_get_push_history', array($this, 'ajax_get_push_history'));
            add_action('wp_ajax_manual_push_url', array($this, 'ajax_manual_push_url'));
            add_action('wp_ajax_add_custom_engine', array($this, 'ajax_add_custom_engine'));
            add_action('wp_ajax_delete_engine', array($this, 'ajax_delete_engine'));
            add_action('wp_ajax_get_engines', array($this, 'ajax_get_engines'));
            add_action('wp_ajax_test_all_engines', array($this, 'ajax_test_all_engines'));

            // 收录批量检测（高级功能）
            add_action('wp_ajax_spider_indexing_batch_check', array($this, 'ajax_indexing_batch_check'));
            add_action('wp_ajax_spider_indexing_batch_stop', array($this, 'ajax_indexing_batch_stop'));
            add_action('wp_ajax_spider_indexing_batch_progress', array($this, 'ajax_indexing_batch_progress'));
            // 批量任务调度与执行（小批量，避免高负载）
            add_action('wp_spider_indexing_batch_event', array($this, 'handle_indexing_batch_event'));

            // 分析：错误统计与热力图
            add_action('wp_ajax_spider_error_stats', array($this, 'ajax_spider_error_stats'));
            add_action('wp_ajax_spider_heatmap_24h', array($this, 'ajax_spider_heatmap_24h'));
            add_action('wp_ajax_spider_sources_premium', array($this, 'ajax_spider_sources_premium'));
            
            // 文章发布时的自动推送
            add_action('publish_post', array($this, 'auto_push_new_post'), 10, 2);
            add_action('publish_page', array($this, 'auto_push_new_post'), 10, 2);
            
            // 广告相关AJAX
            add_action('wp_ajax_spider_track_ad_click', array($this, 'handle_ad_click_tracking'));
            add_action('wp_ajax_spider_get_ads_data', array($this, 'get_ads_data'));
            
            // 添加底部标志到所有管理页面
            add_action('admin_footer', array($this, 'add_footer_logo'));
            
            // 开始监控蜘蛛访问
            add_action('template_redirect', array($this, 'monitor_spider_visits'));
        }
        // 通过搜索引擎查询（site/inurl）判定是否收录
        private function check_indexing_by_search($engine, $url) {
            $result = array('done' => false, 'indexed' => false, 'evidence' => null);
            $host = wp_parse_url($url, PHP_URL_HOST);
            if (empty($host)) { return $result; }

            // 根据引擎构造查询URL（公开接口，注意频率）
            switch ($engine) {
                case 'baidu':
                    $q = 'site:' . $host . ' ' . $url;
                    $searchUrl = 'https://www.baidu.com/s?wd=' . urlencode($q);
                    $evidenceSelector = '/<div class="result|<div class=\"c-container/';
                    break;
                case 'bing':
                    $q = 'site:' . $host . ' ' . $url;
                    $searchUrl = 'https://www.bing.com/search?q=' . urlencode($q);
                    $evidenceSelector = '/<li class="b_algo"/';
                    break;
                case 'google':
                    $q = 'site:' . $host . ' ' . $url;
                    $searchUrl = 'https://www.google.com/search?q=' . urlencode($q);
                    $evidenceSelector = '/<div class="g"/';
                    break;
                case '360':
                    $q = 'site:' . $host . ' ' . $url;
                    $searchUrl = 'https://www.so.com/s?q=' . urlencode($q);
                    $evidenceSelector = '/<li class="res-list"/';
                    break;
                case 'sogou':
                    $q = 'site:' . $host . ' ' . $url;
                    $searchUrl = 'https://www.sogou.com/web?query=' . urlencode($q);
                    $evidenceSelector = '/<div class="vrwrap|<div class="rb"/';
                    break;
                default:
                    return $result;
            }

            $resp = wp_remote_get($searchUrl, array(
                'timeout' => 10,
                'headers' => array(
                    'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36'
                )
            ));
            if (is_wp_error($resp)) { return $result; }
            $code = wp_remote_retrieve_response_code($resp);
            $body = wp_remote_retrieve_body($resp);
            if ($code !== 200 || empty($body)) { return $result; }

            $hasHit = preg_match($evidenceSelector, $body) === 1;
            $result['done'] = true;
            $result['indexed'] = $hasHit;
            $result['evidence'] = array('query' => $q, 'searchUrl' => $searchUrl);
            return $result;
        }

        // 数据库结构升级：按需新增字段，避免致命错误
        private function ensure_schema_upgrades() {
            global $wpdb;
            $visits_table = $wpdb->prefix . 'spider_visits';
            // 如果表不存在，直接返回（初始化流程会创建）
            $exists = ($wpdb->get_var("SHOW TABLES LIKE '$visits_table'") == $visits_table);
            if (!$exists) { return; }

            // hostname 列
            $col = $wpdb->get_var($wpdb->prepare(
                "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = %s AND TABLE_NAME = %s AND COLUMN_NAME = 'hostname'",
                DB_NAME, $visits_table
            ));
            if (!$col) {
                $wpdb->query("ALTER TABLE $visits_table ADD COLUMN hostname varchar(255) NULL AFTER rule_tag");
            }

            // is_verified_bot 列
            $col = $wpdb->get_var($wpdb->prepare(
                "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = %s AND TABLE_NAME = %s AND COLUMN_NAME = 'is_verified_bot'",
                DB_NAME, $visits_table
            ));
            if (!$col) {
                $wpdb->query("ALTER TABLE $visits_table ADD COLUMN is_verified_bot tinyint(1) DEFAULT 0 AFTER hostname");
            }

            // verified_source 列
            $col = $wpdb->get_var($wpdb->prepare(
                "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = %s AND TABLE_NAME = %s AND COLUMN_NAME = 'verified_source'",
                DB_NAME, $visits_table
            ));
            if (!$col) {
                $wpdb->query("ALTER TABLE $visits_table ADD COLUMN verified_source varchar(50) NULL AFTER is_verified_bot");
            }
        }
        // 精准验证：对可验证的官方蜘蛛做反向DNS校验
        private function verify_bot($spider_name, $user_agent, $ip_address) {
            // 为了性能考虑，暂时禁用 DNS 验证，避免阻塞数据写入
            // 如果确实需要验证，可以考虑异步处理或缓存结果
            return false;
            
            /*
            $verifiable = array(
                'Googlebot' => array('domains' => array('.googlebot.com', '.google.com')),
                'Bingbot' => array('domains' => array('.search.msn.com')),
                'YandexBot' => array('domains' => array('.yandex.ru', '.yandex.net')),
                'Applebot' => array('domains' => array('.applebot.apple.com')),
                'DuckDuckBot' => array('domains' => array('.duckduckgo.com')),
            );
            if (!isset($verifiable[$spider_name])) {
                return false;
            }
            
            // 设置较短的超时时间，避免阻塞
            $old_timeout = ini_get('default_socket_timeout');
            ini_set('default_socket_timeout', 2);
            
            try {
                $host = @gethostbyaddr($ip_address);
                if (!$host) { 
                    ini_set('default_socket_timeout', $old_timeout);
                    return false; 
                }
                
                $ok = false;
                foreach ($verifiable[$spider_name]['domains'] as $suffix) {
                    if (substr($host, -strlen($suffix)) === $suffix) { 
                        $ok = true; 
                        break; 
                    }
                }
                if (!$ok) { 
                    ini_set('default_socket_timeout', $old_timeout);
                    return false; 
                }
                
                $ipCheck = @gethostbyname($host);
                ini_set('default_socket_timeout', $old_timeout);
                return $ipCheck === $ip_address;
            } catch (Exception $e) {
                ini_set('default_socket_timeout', $old_timeout);
                error_log("Spider Monitor: DNS verification failed: " . $e->getMessage());
                return false;
            }
            */
        }
        
        public function init() {
            // 加载文本域
            load_plugin_textdomain('wp-spider-monitor', false, dirname(plugin_basename(__FILE__)) . '/languages');
            
            // 检查并创建数据库表
            $this->check_and_create_tables();
        }
        
        public function activate() {
            $this->create_tables();
            
            // 设置默认选项 - 完整版
            add_option('wp_spider_monitor_settings', array(
                'plugin_author' => 'Eric',
                'author_website' => 'https://zibovip.top',
                'max_pages' => 100,
                'delay_between_requests' => 1,
                'user_agent' => 'WordPress Spider Monitor/2.1.0 (https://zibovip.top)',
                'timeout' => 30,
                'follow_redirects' => true,
                'check_external_links' => false,
                'enable_push' => true,
                'auto_push_new_posts' => true,
                'push_delay' => 5,
                'max_push_per_hour' => 100,
                'enable_logging' => true,
                'log_level' => 'info',
                'interface_theme' => 'modern',
                'show_admin_notice' => true,
                'enable_cron' => true,
                'cron_interval' => 'hourly',
                'cleanup_old_data' => true,
                'data_retention_days' => 90,
                'enable_geoip' => true,
                'enable_device_detection' => true,
                'enable_premium_features' => false
            ));
            
            // 设置作者信息
            add_option('wp_spider_monitor_author_info', array(
                'author' => 'Eric',
                'website' => 'https://zibovip.top',
                'email' => 'eric@zibovip.top',
                'version' => '2.1.0',
                'activation_date' => current_time('mysql')
            ));
            
            // 设置推送配置
            add_option('wp_spider_monitor_push_settings', array(
                'enabled_engines' => array(),
                'batch_size' => 10,
                'retry_failed' => true,
                'max_retries' => 3,
                'retry_delay' => 300,
                'enable_scheduled_push' => true,
                'scheduled_time' => '02:00',
                'exclude_post_types' => array('attachment', 'revision'),
                'exclude_categories' => array(),
                'require_featured_image' => false,
                'min_word_count' => 100
            ));
        }
        
        public function deactivate() {
            // 清理所有定时任务
            wp_clear_scheduled_hook('wp_spider_monitor_cron');
            wp_clear_scheduled_hook('wp_spider_monitor_daily_reset');
            wp_clear_scheduled_hook('wp_spider_monitor_push_cron');
            wp_clear_scheduled_hook('wp_spider_monitor_cleanup');
            wp_clear_scheduled_hook('wp_spider_monitor_quota_reset');
            
            // 记录停用时间
            update_option('wp_spider_monitor_deactivation_date', current_time('mysql'));
        }
        
        public function init_default_push_config() {
            global $wpdb;
            $table_name = $wpdb->prefix . 'spider_push_config';
            
            // 清理系统内置引擎（保留用户自定义）
            $wpdb->query("DELETE FROM $table_name WHERE is_system = 1");
            
            $default_engines = array(
                array(
                    'engine_name' => '百度推送',
                    'engine_type' => 'baidu',
                    'api_url' => 'http://data.zz.baidu.com/urls',
                    'api_key' => '',
                    'site_url' => 'https://zibovip.top',
                    'site_token' => '',
                    'push_method' => 'POST',
                    'content_type' => 'text/plain',
                    'daily_quota' => 3000,
                    'timeout_seconds' => 30,
                    'is_active' => 1,
                    'is_system' => 1,
                    'is_premium' => 0,
                    'success_pattern' => 'success',
                    'error_pattern' => 'error'
                ),
                array(
                    'engine_name' => '必应推送',
                    'engine_type' => 'bing',
                    'api_url' => 'https://ssl.bing.com/webmaster/api.svc/json/SubmitUrlBatch',
                    'api_key' => '',
                    'site_url' => 'https://zibovip.top',
                    'site_token' => '',
                    'push_method' => 'POST',
                    'content_type' => 'application/json',
                    'daily_quota' => 100,
                    'timeout_seconds' => 30,
                    'is_active' => 1,
                    'is_system' => 1,
                    'is_premium' => 0,
                    'success_pattern' => 'Success',
                    'error_pattern' => 'Error'
                ),
                array(
                    'engine_name' => '谷歌搜索推送',
                    'engine_type' => 'google',
                    'api_url' => 'https://indexing.googleapis.com/v3/urlNotifications:publish',
                    'api_key' => '',
                    'site_url' => 'https://zibovip.top',
                    'site_token' => '',
                    'push_method' => 'POST',
                    'content_type' => 'application/json',
                    'daily_quota' => 200,
                    'timeout_seconds' => 60,
                    'is_active' => 1,
                    'is_system' => 1,
                    'is_premium' => 0,
                    'success_pattern' => 'URL_NOTIFICATION_PUBLISH_REQUEST',
                    'error_pattern' => 'error'
                ),
                array(
                    'engine_name' => '360搜索推送',
                    'engine_type' => '360',
                    'api_url' => 'http://info.so.com/urls',
                    'api_key' => '',
                    'site_url' => 'https://zibovip.top',
                    'site_token' => '',
                    'push_method' => 'POST',
                    'content_type' => 'text/plain',
                    'daily_quota' => 1000,
                    'timeout_seconds' => 30,
                    'is_active' => 1,
                    'is_system' => 1,
                    'is_premium' => 0,
                    'success_pattern' => 'success',
                    'error_pattern' => 'error'
                ),
                array(
                    'engine_name' => '字节搜索推送',
                    'engine_type' => 'bytedance',
                    'api_url' => 'https://api.indexnow.org/indexnow',
                    'api_key' => '',
                    'site_url' => 'https://zibovip.top',
                    'site_token' => '',
                    'push_method' => 'POST',
                    'content_type' => 'application/json',
                    'daily_quota' => 1000,
                    'timeout_seconds' => 30,
                    'is_active' => 1,
                    'is_system' => 1,
                    'is_premium' => 0,
                    'success_pattern' => 'Success',
                    'error_pattern' => 'Error'
                )
            );
            
            foreach ($default_engines as $engine) {
                $exists = $wpdb->get_var($wpdb->prepare(
                    "SELECT COUNT(*) FROM $table_name WHERE engine_name = %s",
                    $engine['engine_name']
                ));
                
                if ($exists == 0) {
                    $wpdb->insert($table_name, $engine);
                }
            }
        }
        
        public function init_quota_system() {
            global $wpdb;
            $table_name = $wpdb->prefix . 'spider_quota';
            $today = current_time('Y-m-d');
            
            $quota_settings = array(
                'baidu' => array('daily_quota' => 3000, 'reset_time' => '00:00'),
                'bing' => array('daily_quota' => 100, 'reset_time' => '00:00'),
                'google' => array('daily_quota' => 200, 'reset_time' => '00:00'),
                '360' => array('daily_quota' => 1000, 'reset_time' => '00:00'),
                'bytedance' => array('daily_quota' => 1000, 'reset_time' => '00:00')
            );
            
            foreach ($quota_settings as $engine_type => $settings) {
                $exists = $wpdb->get_var($wpdb->prepare(
                    "SELECT COUNT(*) FROM $table_name WHERE engine_type = %s AND quota_date = %s",
                    $engine_type, $today
                ));
                
                if ($exists == 0) {
                    $wpdb->insert($table_name, array(
                        'engine_name' => $this->get_engine_name_by_type($engine_type),
                        'engine_type' => $engine_type,
                        'daily_quota' => $settings['daily_quota'],
                        'used_quota' => 0,
                        'remaining_quota' => $settings['daily_quota'],
                        'quota_date' => $today,
                        'reset_time' => $settings['reset_time'],
                        'last_reset' => current_time('mysql'),
                        'next_reset' => current_time('mysql'),
                        'is_active' => 1
                    ));
                }
            }
        }
        
        private function get_engine_name_by_type($type) {
            $names = array(
                'baidu' => '百度推送',
                'bing' => '必应推送',
                'google' => '谷歌搜索推送',
                '360' => '360搜索推送',
                'bytedance' => '字节搜索推送'
            );
            return isset($names[$type]) ? $names[$type] : '未知引擎';
        }
        
        public function get_configured_engines() {
            global $wpdb;
            $table_name = $wpdb->prefix . 'spider_push_config';
            return $wpdb->get_results("SELECT * FROM $table_name WHERE is_system = 1 ORDER BY engine_name", ARRAY_A);
        }
        
        public function get_engine_config($engine_type) {
            global $wpdb;
            $table_name = $wpdb->prefix . 'spider_push_config';
            return $wpdb->get_row($wpdb->prepare(
                "SELECT * FROM $table_name WHERE engine_type = %s AND is_system = 1",
                $engine_type
            ), ARRAY_A);
        }
        
        public function update_engine_config($engine_type, $config_data) {
            global $wpdb;
            $table_name = $wpdb->prefix . 'spider_push_config';
            
            return $wpdb->update(
                $table_name,
                $config_data,
                array('engine_type' => $engine_type, 'is_system' => 1),
                array('%s', '%d'),
                array('%s', '%d')
            );
        }
        
        public function check_and_create_tables() {
            global $wpdb;
            
            $spider_visits_table = $wpdb->prefix . 'spider_visits';
            $spider_stats_table = $wpdb->prefix . 'spider_stats';
            $user_theme_table = $wpdb->prefix . 'spider_user_theme';
            $spider_block_table = $wpdb->prefix . 'spider_block_rules';
            $article_crawl_table = $wpdb->prefix . 'spider_article_crawl';
            
            // 检查表是否存在
            $visits_exists = $wpdb->get_var("SHOW TABLES LIKE '$spider_visits_table'") == $spider_visits_table;
            $stats_exists = $wpdb->get_var("SHOW TABLES LIKE '$spider_stats_table'") == $spider_stats_table;
            $user_theme_exists = $wpdb->get_var("SHOW TABLES LIKE '$user_theme_table'") == $user_theme_table;
            $block_exists = $wpdb->get_var("SHOW TABLES LIKE '$spider_block_table'") == $spider_block_table;
            $article_exists = $wpdb->get_var("SHOW TABLES LIKE '$article_crawl_table'") == $article_crawl_table;
            
            // 如果表不存在，则创建
            if (!$visits_exists || !$stats_exists || !$user_theme_exists || !$block_exists || !$article_exists) {
                $this->create_tables();
                
                // 再次检查表是否创建成功
                $visits_exists_after = $wpdb->get_var("SHOW TABLES LIKE '$spider_visits_table'") == $spider_visits_table;
                $stats_exists_after = $wpdb->get_var("SHOW TABLES LIKE '$spider_stats_table'") == $spider_stats_table;
                $user_theme_exists_after = $wpdb->get_var("SHOW TABLES LIKE '$user_theme_table'") == $user_theme_table;
                $block_exists_after = $wpdb->get_var("SHOW TABLES LIKE '$spider_block_table'") == $spider_block_table;
                $article_exists_after = $wpdb->get_var("SHOW TABLES LIKE '$article_crawl_table'") == $article_crawl_table;
                
                if (!$visits_exists_after || !$stats_exists_after || !$user_theme_exists_after || !$block_exists_after || !$article_exists_after) {
                    // 如果创建失败，记录错误
                    error_log('WordPress Spider Monitor: 数据库表创建失败');
                }
            }
        }
        
        public function create_tables() {
            global $wpdb;
            
            $charset_collate = $wpdb->get_charset_collate();
            
            // 蜘蛛访问记录表 - 增强版
            $spider_visits_table = $wpdb->prefix . 'spider_visits';
            $sql1 = "CREATE TABLE $spider_visits_table (
                id bigint(20) NOT NULL AUTO_INCREMENT,
                spider_name varchar(100) NOT NULL,
                bot_type varchar(50) DEFAULT 'unknown',
                user_agent text NOT NULL,
                ip_address varchar(45) NOT NULL,
                url varchar(500) NOT NULL,
                referer varchar(500),
                visit_time datetime DEFAULT CURRENT_TIMESTAMP,
                response_code int(3) DEFAULT 200,
                response_time decimal(10,3) DEFAULT 0.000,
                page_title varchar(255),
                request_method varchar(10) DEFAULT 'GET',
                content_type varchar(100),
                content_length int(11),
                server_name varchar(100),
                query_string text,
                user_agent_hash varchar(32),
                session_id varchar(100),
                is_mobile tinyint(1) DEFAULT 0,
                device_type varchar(20) DEFAULT 'desktop',
                os varchar(50),
                browser varchar(50),
                country varchar(2),
                region varchar(50),
                city varchar(50),
                latitude decimal(10,8),
                longitude decimal(11,8),
                is_blocked tinyint(1) DEFAULT 0,
                is_ignored tinyint(1) DEFAULT 0,
                rule_tag varchar(50),
                hostname varchar(255),
                is_verified_bot tinyint(1) DEFAULT 0,
                verified_source varchar(50),
                url_type varchar(50) DEFAULT 'unknown',
                post_id bigint(20) DEFAULT 0,
                is_fake_bot tinyint(1) DEFAULT 0,
                fake_reason varchar(255),
                PRIMARY KEY (id),
                KEY spider_name (spider_name),
                KEY visit_time (visit_time),
                KEY url (url(191)),
                KEY ip_address (ip_address),
                KEY response_code (response_code),
                KEY user_agent_hash (user_agent_hash),
                KEY country (country),
                KEY device_type (device_type),
                KEY is_mobile (is_mobile),
                KEY session_id (session_id),
                KEY is_blocked (is_blocked),
                KEY is_ignored (is_ignored),
                KEY rule_tag (rule_tag),
                KEY url_type (url_type),
                KEY post_id (post_id),
                KEY is_fake_bot (is_fake_bot),
                KEY composite_visit (spider_name, visit_time, response_code),
                KEY composite_url_type (url_type, visit_time),
                KEY composite_spider_url (spider_name, url(191))
            ) $charset_collate;";
            
            // 蜘蛛统计表 - 增强版
            $spider_stats_table = $wpdb->prefix . 'spider_stats';
            $sql2 = "CREATE TABLE $spider_stats_table (
                id bigint(20) NOT NULL AUTO_INCREMENT,
                spider_name varchar(100) NOT NULL,
                visit_date date NOT NULL,
                visit_count int(11) DEFAULT 0,
                unique_pages int(11) DEFAULT 0,
                unique_ips int(11) DEFAULT 0,
                total_response_time decimal(10,3) DEFAULT 0,
                avg_response_time decimal(10,3) DEFAULT 0,
                min_response_time decimal(10,3) DEFAULT 0,
                max_response_time decimal(10,3) DEFAULT 0,
                last_visit datetime,
                error_count int(11) DEFAULT 0,
                success_count int(11) DEFAULT 0,
                redirect_count int(11) DEFAULT 0,
                mobile_visits int(11) DEFAULT 0,
                desktop_visits int(11) DEFAULT 0,
                tablet_visits int(11) DEFAULT 0,
                PRIMARY KEY (id),
                UNIQUE KEY spider_date (spider_name, visit_date),
                KEY spider_name (spider_name),
                KEY visit_date (visit_date),
                KEY last_visit (last_visit),
                KEY composite_stats (spider_name, visit_date, visit_count)
            ) $charset_collate;";
            
            // URL推送记录表 - 完整版
            $push_urls_table = $wpdb->prefix . 'spider_push_urls';
            $sql3 = "CREATE TABLE $push_urls_table (
                id bigint(20) NOT NULL AUTO_INCREMENT,
                url varchar(500) NOT NULL,
                post_id bigint(20),
                post_type varchar(20) DEFAULT 'post',
                post_title varchar(255),
                post_date datetime,
                push_time datetime DEFAULT CURRENT_TIMESTAMP,
                status varchar(20) DEFAULT 'pending',
                response_data text,
                response_code int(3),
                response_message varchar(255),
                search_engines text,
                success_engines text,
                failed_engines text,
                total_engines int(11) DEFAULT 0,
                success_count int(11) DEFAULT 0,
                fail_count int(11) DEFAULT 0,
                priority int(11) DEFAULT 5,
                retry_count int(11) DEFAULT 0,
                max_retries int(11) DEFAULT 3,
                next_retry datetime,
                is_scheduled tinyint(1) DEFAULT 0,
                scheduled_time datetime,
                user_id bigint(20),
                user_ip varchar(45),
                user_agent text,
                PRIMARY KEY (id),
                KEY url (url(191)),
                KEY post_id (post_id),
                KEY push_time (push_time),
                KEY status (status),
                KEY post_type (post_type),
                KEY response_code (response_code),
                KEY priority (priority),
                KEY next_retry (next_retry),
                KEY is_scheduled (is_scheduled),
                KEY user_id (user_id),
                KEY composite_push (post_id, status, push_time)
            ) $charset_collate;";
            
            // 搜索引擎推送配置表 - 完整版
            $push_config_table = $wpdb->prefix . 'spider_push_config';
            $sql4 = "CREATE TABLE $push_config_table (
                id bigint(20) NOT NULL AUTO_INCREMENT,
                engine_name varchar(100) NOT NULL,
                engine_type varchar(50) DEFAULT 'custom',
                api_url varchar(500) NOT NULL,
                api_key varchar(255),
                site_url varchar(255),
                site_token varchar(255),
                is_active tinyint(1) DEFAULT 1,
                is_system tinyint(1) DEFAULT 0,
                is_premium tinyint(1) DEFAULT 0,
                push_method varchar(20) DEFAULT 'POST',
                content_type varchar(50) DEFAULT 'application/json',
                headers text,
                request_body text,
                url_parameter varchar(100),
                api_format varchar(20) DEFAULT 'json',
                success_pattern varchar(255),
                error_pattern varchar(255),
                daily_quota int(11) DEFAULT 1000,
                used_quota int(11) DEFAULT 0,
                quota_reset_time varchar(5) DEFAULT '00:00',
                last_push_date date,
                today_pushed int(11) DEFAULT 0,
                total_pushed int(11) DEFAULT 0,
                total_success int(11) DEFAULT 0,
                total_failed int(11) DEFAULT 0,
                success_rate decimal(5,2) DEFAULT 0.00,
                average_response_time decimal(10,3) DEFAULT 0.000,
                timeout_seconds int(11) DEFAULT 30,
                retry_enabled tinyint(1) DEFAULT 1,
                max_retries int(11) DEFAULT 3,
                retry_delay int(11) DEFAULT 5,
                rate_limit int(11) DEFAULT 10,
                rate_limit_period int(11) DEFAULT 60,
                custom_parameters text,
                webhook_url varchar(500),
                created_by bigint(20) DEFAULT 1,
                created_time datetime DEFAULT CURRENT_TIMESTAMP,
                updated_by bigint(20),
                updated_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
                PRIMARY KEY (id),
                UNIQUE KEY engine_name (engine_name),
                UNIQUE KEY engine_type_site (engine_type, site_url),
                KEY is_active (is_active),
                KEY is_system (is_system),
                KEY engine_type (engine_type),
                KEY created_time (created_time),
                KEY updated_time (updated_time),
                KEY quota_status (is_active, daily_quota, used_quota)
            ) $charset_collate;";
            
            // 推送日志表 - 详细记录
            $push_log_table = $wpdb->prefix . 'spider_push_log';
            $sql5 = "CREATE TABLE $push_log_table (
                id bigint(20) NOT NULL AUTO_INCREMENT,
                push_id bigint(20),
                engine_id bigint(20),
                engine_name varchar(100),
                url varchar(500) NOT NULL,
                post_id bigint(20),
                request_data text,
                response_data text,
                response_code int(3),
                response_time decimal(10,3) DEFAULT 0.000,
                status varchar(20) DEFAULT 'pending',
                error_message text,
                retry_count int(11) DEFAULT 0,
                ip_address varchar(45),
                user_agent text,
                created_time datetime DEFAULT CURRENT_TIMESTAMP,
                PRIMARY KEY (id),
                KEY push_id (push_id),
                KEY engine_id (engine_id),
                KEY url (url(191)),
                KEY post_id (post_id),
                KEY status (status),
                KEY response_code (response_code),
                KEY created_time (created_time),
                KEY composite_log (engine_id, status, created_time)
            ) $charset_collate;";
            
            // 搜索引擎配额表
            $quota_table = $wpdb->prefix . 'spider_quota';
            $sql6 = "CREATE TABLE $quota_table (
                id bigint(20) NOT NULL AUTO_INCREMENT,
                engine_name varchar(100) NOT NULL,
                engine_type varchar(50) NOT NULL,
                daily_quota int(11) DEFAULT 1000,
                used_quota int(11) DEFAULT 0,
                remaining_quota int(11) DEFAULT 1000,
                quota_date date NOT NULL,
                reset_time time DEFAULT '00:00:00',
                last_reset datetime,
                next_reset datetime,
                is_active tinyint(1) DEFAULT 1,
                created_time datetime DEFAULT CURRENT_TIMESTAMP,
                updated_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
                PRIMARY KEY (id),
                UNIQUE KEY engine_date (engine_type, quota_date),
                KEY engine_name (engine_name),
                KEY quota_date (quota_date),
                KEY is_active (is_active),
                KEY remaining_quota (remaining_quota)
            ) $charset_collate;";
            
            // URL收录状态表
            $indexing_table = $wpdb->prefix . 'spider_indexing_status';
            $sql7a = "CREATE TABLE $indexing_table (
                id bigint(20) NOT NULL AUTO_INCREMENT,
                url varchar(500) NOT NULL,
                post_id bigint(20),
                engine_type varchar(50) NOT NULL,
                status varchar(20) DEFAULT 'unknown',
                last_checked datetime,
                first_seen datetime,
                last_spider_visit datetime,
                http_status int(3),
                canonical_url varchar(500),
                robots_meta varchar(100),
                sitemap_included tinyint(1) DEFAULT 0,
                notes text,
                created_time datetime DEFAULT CURRENT_TIMESTAMP,
                updated_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
                PRIMARY KEY (id),
                UNIQUE KEY idx_unique (url(191), engine_type),
                KEY post_id (post_id),
                KEY engine_type (engine_type),
                KEY status (status),
                KEY last_checked (last_checked)
            ) $charset_collate;";
            
            // 用户主题设置表
            $user_theme_table = $wpdb->prefix . 'spider_user_theme';
            $sql7 = "CREATE TABLE $user_theme_table (
                id bigint(20) NOT NULL AUTO_INCREMENT,
                user_id bigint(20) NOT NULL,
                theme_name varchar(50) NOT NULL DEFAULT 'modern',
                updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
                PRIMARY KEY (id),
                UNIQUE KEY user_theme (user_id),
                KEY theme_name (theme_name),
                KEY updated_at (updated_at)
            ) $charset_collate;";
            
            require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
            dbDelta($sql1);
            dbDelta($sql2);
            dbDelta($sql3);
            dbDelta($sql4);
            dbDelta($sql5);
            dbDelta($sql6);
            dbDelta($sql7a);
            dbDelta($sql7);
            
            // URL聚合统计表
            $url_stats_table = $wpdb->prefix . 'spider_url_stats';
            $sql8 = "CREATE TABLE $url_stats_table (
                id bigint(20) NOT NULL AUTO_INCREMENT,
                url varchar(500) NOT NULL,
                post_id bigint(20),
                last_visit datetime,
                visit_count int(11) DEFAULT 0,
                last_status int(3),
                avg_response_time decimal(10,3) DEFAULT 0.000,
                last_spider varchar(100),
                first_seen datetime DEFAULT CURRENT_TIMESTAMP,
                last_status_change datetime,
                PRIMARY KEY (id),
                UNIQUE KEY url_unique (url(191)),
                KEY post_id (post_id),
                KEY last_visit (last_visit),
                KEY last_status (last_status),
                KEY first_seen (first_seen)
            ) $charset_collate;";
            dbDelta($sql8);
            
            // 蜘蛛拦截规则表
            $spider_block_table = $wpdb->prefix . 'spider_block_rules';
            $sql_block = "CREATE TABLE $spider_block_table (
                id bigint(20) NOT NULL AUTO_INCREMENT,
                spider_name varchar(100),
                ip_address varchar(45),
                ip_range varchar(50),
                block_type enum('name','ip','range','name_ip') NOT NULL DEFAULT 'name',
                is_active tinyint(1) DEFAULT 1,
                created_at datetime DEFAULT CURRENT_TIMESTAMP,
                updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
                PRIMARY KEY (id),
                KEY spider_name (spider_name),
                KEY ip_address (ip_address),
                KEY block_type (block_type),
                KEY is_active (is_active)
            ) $charset_collate;";
            dbDelta($sql_block);
            
            // 文章爬取统计表
            $article_crawl_table = $wpdb->prefix . 'spider_article_crawl';
            $sql_article = "CREATE TABLE $article_crawl_table (
                id bigint(20) NOT NULL AUTO_INCREMENT,
                post_id bigint(20) NOT NULL,
                post_type varchar(20) NOT NULL,
                post_title varchar(255),
                post_url varchar(500),
                spider_name varchar(100) NOT NULL,
                crawl_count int(11) DEFAULT 0,
                last_crawl datetime,
                outbound_links int(11) DEFAULT 0,
                inbound_links int(11) DEFAULT 0,
                is_indexed tinyint(1) DEFAULT 0,
                crawl_date date NOT NULL,
                PRIMARY KEY (id),
                UNIQUE KEY post_spider_date (post_id, spider_name, crawl_date),
                KEY post_id (post_id),
                KEY spider_name (spider_name),
                KEY crawl_date (crawl_date),
                KEY post_type (post_type),
                KEY is_indexed (is_indexed)
            ) $charset_collate;";
            dbDelta($sql_article);

            // 链接规则表（动态代替死数据）
            $rules_table = $wpdb->prefix . 'spider_link_rules';
            $sql9 = "CREATE TABLE $rules_table (
                id bigint(20) NOT NULL AUTO_INCREMENT,
                rule_key varchar(50) NOT NULL,
                title varchar(100) NOT NULL,
                rule_value text,
                is_enabled tinyint(1) DEFAULT 1,
                updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
                PRIMARY KEY (id),
                UNIQUE KEY rule_key (rule_key),
                KEY is_enabled (is_enabled)
            ) $charset_collate;";
            dbDelta($sql9);

            // 初始化默认规则（仅首次）
            $exists = $wpdb->get_var("SELECT COUNT(*) FROM $rules_table");
            if (intval($exists) === 0) {
                $defaults = array(
                    array('rule_key' => 'home', 'title' => '首页', 'rule_value' => ''),
                    array('rule_key' => 'single', 'title' => '文章页', 'rule_value' => ''),
                    array('rule_key' => 'page', 'title' => '独立页', 'rule_value' => ''),
                    array('rule_key' => 'category', 'title' => '分类页', 'rule_value' => ''),
                    array('rule_key' => 'tag', 'title' => '标签页', 'rule_value' => ''),
                    array('rule_key' => 'search', 'title' => '搜索页', 'rule_value' => ''),
                    array('rule_key' => 'author', 'title' => '作者页', 'rule_value' => ''),
                    array('rule_key' => 'feed', 'title' => 'Feed', 'rule_value' => '')
                );
                foreach ($defaults as $r) { $wpdb->insert($rules_table, $r); }
            }
            
            // 更新选项标记表已创建
            update_option('wp_spider_monitor_tables_created', true);
            update_option('wp_spider_monitor_db_version', '2.1.0');
            
            // 初始化默认搜索引擎配置
            $this->init_default_push_config();
            
            // 初始化配额表
            $this->init_quota_system();
        }
        
        public function add_admin_menu() {
            add_menu_page(
                '蜘蛛分析',
                '蜘蛛分析',
                'manage_options',
                'wp-spider-monitor',
                array($this, 'spa_dashboard_page'),
                'dashicons-search',
                30
            );
            
            // 移除所有子菜单，使用SPA单页应用
            // 所有功能都通过SPA路由在同一个页面中切换
            
            // // 许可证管理
            // add_submenu_page(
            //     'wp-spider-monitor',
            //     '许可证管理',
            //     '升级PRO版',
            //     'manage_options',
            //     'spider-license',
            //     array($this, 'render_license_page')
            // );
            
            // SPA测试页面（仅开发环境）
            if (defined('WP_DEBUG') && WP_DEBUG) {
                add_submenu_page(
                    'wp-spider-monitor',
                    'SPA测试',
                    'SPA测试',
                    'manage_options',
                    'spider-spa-test',
                    array($this, 'spa_test_page')
                );
                
                add_submenu_page(
                    'wp-spider-monitor',
                    '简单SPA测试',
                    '简单SPA测试',
                    'manage_options',
                    'spider-simple-spa-test',
                    array($this, 'simple_spa_test_page')
                );
            }
            
            // 添加自定义CSS到后台
            add_action('admin_head', array($this, 'add_pro_menu_style'));
        }
        
        public function simple_push_config_page() {
            include WP_SPIDER_MONITOR_PLUGIN_PATH . 'templates/simple-engines-config.php';
        }
        
        // 新的页面处理函数
        public function spider_overview_page() {
            include WP_SPIDER_MONITOR_PLUGIN_PATH . 'templates/spider-overview.php';
        }
        
        public function spider_logs_page() {
            include WP_SPIDER_MONITOR_PLUGIN_PATH . 'templates/records-management.php';
        }
        
        public function spider_list_page() {
            include WP_SPIDER_MONITOR_PLUGIN_PATH . 'templates/spider-list.php';
        }
        
        public function settings_page() {
            include WP_SPIDER_MONITOR_PLUGIN_PATH . 'templates/settings-page.php';
        }
        
        public function settings_hub_page() {
            include WP_SPIDER_MONITOR_PLUGIN_PATH . 'templates/settings-hub.php';
        }
        
        public function access_paths_page() {
            include WP_SPIDER_MONITOR_PLUGIN_PATH . 'templates/access-paths.php';
        }
        
        public function article_crawl_page() {
            include WP_SPIDER_MONITOR_PLUGIN_PATH . 'templates/article-crawl.php';
        }
        
        public function enqueue_admin_scripts($hook) {
            if (strpos($hook, 'wp-spider-monitor') === false) {
                return;
            }

            // 获取当前用户主题设置
            $current_theme = $this->get_user_theme();
            
            // 加载主题预加载样式（防止闪烁）
            wp_enqueue_style('wp-spider-monitor-theme-preload', WP_SPIDER_MONITOR_PLUGIN_URL . 'assets/theme-preload.css', array(), WP_SPIDER_MONITOR_VERSION);
            
            // 加载基础样式
            wp_enqueue_style('wp-spider-monitor-wp-admin', WP_SPIDER_MONITOR_PLUGIN_URL . 'assets/wp-admin-styles.css', array('wp-spider-monitor-theme-preload'), WP_SPIDER_MONITOR_VERSION);
            
            // 加载主题样式
            $theme_styles = array('modern', 'classic', 'minimal', 'dark', 'colorful', 'vibrant', 'cyberpunk', 'nature');
            if (in_array($current_theme, $theme_styles)) {
                wp_enqueue_style('wp-spider-monitor-theme', WP_SPIDER_MONITOR_PLUGIN_URL . 'assets/themes/' . $current_theme . '.css', array('wp-spider-monitor-wp-admin'), WP_SPIDER_MONITOR_VERSION);
            }
            
            // 加载WordPress标准样式
            wp_enqueue_style('wp-color-picker');
            wp_enqueue_style('dashboard');

            // 加载Chart.js库
            wp_enqueue_script('chart-js', 'https://cdn.jsdelivr.net/npm/chart.js@3.9.1/dist/chart.min.js', array(), '3.9.1', true);
            
            // 加载SPA样式
            wp_enqueue_style('wp-spider-monitor-spa', WP_SPIDER_MONITOR_PLUGIN_URL . 'assets/css/spa-styles.css', array('wp-spider-monitor-wp-admin'), WP_SPIDER_MONITOR_VERSION);
            
            // 加载主题相关脚本
            // 先静默控制台输出，避免调试日志干扰
            wp_enqueue_script('wp-spider-console-silencer', WP_SPIDER_MONITOR_PLUGIN_URL . 'assets/js/console-silencer.js', array(), WP_SPIDER_MONITOR_VERSION, false);
            wp_enqueue_script('wp-spider-monitor-theme-init', WP_SPIDER_MONITOR_PLUGIN_URL . 'assets/theme-init.js', array('jquery'), WP_SPIDER_MONITOR_VERSION, true);
            wp_enqueue_script('wp-spider-monitor-theme-switcher', WP_SPIDER_MONITOR_PLUGIN_URL . 'assets/theme-switcher.js', array('jquery', 'chart-js'), WP_SPIDER_MONITOR_VERSION, true);
            wp_enqueue_script('wp-spider-monitor-admin', WP_SPIDER_MONITOR_PLUGIN_URL . 'assets/admin.js', array('jquery', 'wp-color-picker', 'chart-js'), WP_SPIDER_MONITOR_VERSION, true);
            wp_enqueue_script('wp-spider-premium-security', WP_SPIDER_MONITOR_PLUGIN_URL . 'assets/premium-client-security.js', array('jquery'), WP_SPIDER_MONITOR_VERSION, true);
            
            // 加载简单SPA脚本
            wp_enqueue_script('wp-spider-monitor-simple-spa', WP_SPIDER_MONITOR_PLUGIN_URL . 'assets/js/simple-spa.js', array('jquery'), WP_SPIDER_MONITOR_VERSION, true);

            
            
            // 本地化数据 - 提供给所有主题相关脚本使用
            $subscription_features = $this->get_premium_features();
            $is_premium = apply_filters('wp_spider_monitor_is_premium', $this->is_premium_version());
            // 调试：记录本次页面本地化时的授权状态
            if (defined('WP_DEBUG') && WP_DEBUG) {
                $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '';
                error_log('[SpiderMonitor] localize subscription.is_premium=' . ((bool)$is_premium ? 'active' : 'inactive') . ' domain=' . $host);
            }
            wp_localize_script('wp-spider-monitor-theme-switcher', 'wpSpiderMonitor', array(
                'ajax_url' => admin_url('admin-ajax.php'),
                'nonce' => wp_create_nonce('wp_spider_monitor_nonce'),
                'currentTheme' => $current_theme,
                'userTheme' => $this->get_user_theme(),
                'userId' => get_current_user_id(),
                'subscription' => array(
                    'is_premium' => (bool)$is_premium,
                    'features' => array(
                        'export_data' => !empty($subscription_features['export_data']['premium']) ? (bool)$is_premium : true,
                        'clear_data' => !empty($subscription_features['clear_data']['premium']) ? (bool)$is_premium : true,
                        'real_time_update' => !empty($subscription_features['real_time_update']['premium']) ? (bool)$is_premium : true,
                        'advanced_stats' => !empty($subscription_features['advanced_stats']['premium']) ? (bool)$is_premium : true,
                        'multi_site' => !empty($subscription_features['multi_site']['premium']) ? (bool)$is_premium : true,
                        'api_access' => !empty($subscription_features['api_access']['premium']) ? (bool)$is_premium : true
                    )
                )
            ));
        }
        
        public function admin_page() {
            include WP_SPIDER_MONITOR_PLUGIN_PATH . 'templates/admin-page-new.php';
        }

        // 批量检测收录（仅高级订阅）
        public function ajax_indexing_batch_check() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            // 权限检查
            if (!$this->is_premium_version()) {
                wp_send_json_error('需要高级订阅');
            }
            $engine = sanitize_text_field($_POST['engine'] ?? 'baidu');
            $limit = isset($_POST['count']) ? max(1, intval($_POST['count'])) : 0; // 0 表示不限制
            // 初始化批处理状态
            $state = array('engine' => $engine, 'offset' => 0, 'batch_size' => 10, 'processed' => 0, 'limit' => $limit);
            set_transient('spider_indexing_batch_state', $state, 30 * MINUTE_IN_SECONDS);
            // 调度后台事件：首批5秒后开始
            $args = array('engine' => $engine, 'offset' => 0);
            wp_schedule_single_event(time() + 5, 'wp_spider_indexing_batch_event', $args);
            wp_send_json_success(array('started' => true));
        }

        // 手动结束批量检测：清理状态并取消未来的计划事件
        public function ajax_indexing_batch_stop() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            if (!$this->is_premium_version()) {
                wp_send_json_error(array(
                    'message' => '需要高级订阅',
                    'upgrade_url' => admin_url('admin.php?page=spider-license')
                ));
            }
            // 删除状态
            delete_transient('spider_indexing_batch_state');
            // 取消未来计划任务（WP 6.1+ 有 wp_clear_scheduled_hook）
            if (function_exists('wp_clear_scheduled_hook')) {
                wp_clear_scheduled_hook('wp_spider_indexing_batch_event');
            } else {
                // 回退：尝试清空近期计划的事件
                $timestamp = wp_next_scheduled('wp_spider_indexing_batch_event');
                while ($timestamp) {
                    wp_unschedule_event($timestamp, 'wp_spider_indexing_batch_event');
                    $timestamp = wp_next_scheduled('wp_spider_indexing_batch_event');
                }
            }
            wp_send_json_success(array('stopped' => true));
        }

        // 进度查询：返回 processed 与 limit
        public function ajax_indexing_batch_progress() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            $state = get_transient('spider_indexing_batch_state');
            if (!$state) {
                wp_send_json_success(array('running' => false, 'processed' => 0, 'limit' => 0));
            }
            $processed = isset($state['processed']) ? intval($state['processed']) : 0;
            $limit = isset($state['limit']) ? intval($state['limit']) : 0;
            wp_send_json_success(array('running' => true, 'processed' => $processed, 'limit' => $limit));
        }

        // 后台小批量执行：每次仅处理10条，串行请求，降低内存和CPU
        public function handle_indexing_batch_event($args) {
            $engine = isset($args['engine']) ? sanitize_text_field($args['engine']) : 'baidu';
            $state = get_transient('spider_indexing_batch_state');
            $offset = is_array($state) && isset($state['offset']) ? intval($state['offset']) : 0;
            $batch_size = is_array($state) && isset($state['batch_size']) ? intval($state['batch_size']) : 10;
            $processed = is_array($state) && isset($state['processed']) ? intval($state['processed']) : 0;
            $limit = is_array($state) && isset($state['limit']) ? intval($state['limit']) : 0;

            // 取当下站点最近的文章/页面URL，分批处理
            $posts = get_posts(array(
                'post_type' => array('post', 'page'),
                'post_status' => 'publish',
                'numberposts' => $batch_size,
                'offset' => $offset,
                'orderby' => 'date',
                'order' => 'DESC',
                'fields' => 'ids',
                'suppress_filters' => true
            ));

            if (empty($posts)) {
                // 完成，清理状态
                delete_transient('spider_indexing_batch_state');
                return;
            }

            global $wpdb;
            $indexing_table = $wpdb->prefix . 'spider_indexing_status';

            // 收集本批待插入/更新的数据，批量写入
            $now_mysql_time = current_time('mysql');
            $to_insert_rows = array();
            $to_update_items = array();

            foreach ($posts as $post_id) {
                $url = get_permalink($post_id);
                if (!$url) { continue; }
                $searchCheck = $this->check_indexing_by_search($engine, $url);
                $status = 'unknown';
                if ($searchCheck['done']) { $status = $searchCheck['indexed'] ? 'indexed' : 'not_indexed'; }

                // Upsert 记录：先判断是否存在
                $existing_id = $wpdb->get_var($wpdb->prepare(
                    "SELECT id FROM $indexing_table WHERE url = %s AND engine_type = %s",
                    $url, $engine
                ));

                if ($existing_id) {
                    $to_update_items[] = array(
                        'id' => intval($existing_id),
                        'data' => array(
                            'url' => $url,
                            'post_id' => $post_id,
                            'engine_type' => $engine,
                            'status' => $status,
                            'last_checked' => $now_mysql_time
                        )
                    );
                } else {
                    // 收集待插入行
                    $to_insert_rows[] = array(
                        'url' => $url,
                        'post_id' => $post_id,
                        'engine_type' => $engine,
                        'status' => $status,
                        'first_seen' => $now_mysql_time,
                        'last_checked' => $now_mysql_time
                    );
                }

                $processed++;
                if ($limit > 0 && $processed >= $limit) {
                    break; // 本批达到上限，退出循环，后续仍会写入已收集的数据
                }
                // 轻微延迟，避免触发对方反爬与本地CPU尖峰
                usleep(200000); // 200ms
            }

            // 批量插入：每批10条一次性写入数据库
            if (!empty($to_insert_rows)) {
                // 仅当字段一致且数量>0时构造多值INSERT
                $columns = array('url', 'post_id', 'engine_type', 'status', 'first_seen', 'last_checked');
                $placeholders_one = '(%s, %d, %s, %s, %s, %s)';
                $placeholders = array();
                $values = array();
                foreach ($to_insert_rows as $row) {
                    $placeholders[] = $placeholders_one;
                    $values[] = $row['url'];
                    $values[] = intval($row['post_id']);
                    $values[] = $row['engine_type'];
                    $values[] = $row['status'];
                    $values[] = $row['first_seen'];
                    $values[] = $row['last_checked'];
                }
                $sql = "INSERT INTO $indexing_table (`" . implode('`,`', $columns) . "`) VALUES " . implode(',', $placeholders);
                $prepared = $wpdb->prepare($sql, $values);
                $wpdb->query($prepared);
            }

            // 批量更新：逐条UPDATE（保持兼容与安全）
            if (!empty($to_update_items)) {
                foreach ($to_update_items as $item) {
                    $wpdb->update($indexing_table, $item['data'], array('id' => $item['id']));
                }
            }

            // 继续下一批
            $offset += $batch_size;
            // 若已达到限制则清理状态并退出
            if ($limit > 0 && $processed >= $limit) {
                delete_transient('spider_indexing_batch_state');
                return;
            }
            set_transient('spider_indexing_batch_state', array('engine' => $engine, 'offset' => $offset, 'batch_size' => $batch_size, 'processed' => $processed, 'limit' => $limit), 30 * MINUTE_IN_SECONDS);
            wp_schedule_single_event(time() + 10, 'wp_spider_indexing_batch_event', array('engine' => $engine, 'offset' => $offset));
        }
        // 获取收录列表
        public function ajax_get_indexing_list() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_die('权限不足');
            }
            
            global $wpdb;
            $indexing_table = $wpdb->prefix . 'spider_indexing_status';
            
            $engine = sanitize_text_field($_POST['engine'] ?? 'baidu');
            $page = max(1, intval($_POST['page'] ?? 1));
            $per_page = 20;
            $offset = ($page - 1) * $per_page;
            
            if ($engine === 'all') {
                $total = (int) $wpdb->get_var("SELECT COUNT(*) FROM $indexing_table");
                $rows = $wpdb->get_results(
                    $wpdb->prepare(
                        "SELECT * FROM $indexing_table ORDER BY id DESC LIMIT %d OFFSET %d",
                        $per_page, $offset
                    ), ARRAY_A
                );
            } else {
                $total = (int) $wpdb->get_var($wpdb->prepare(
                    "SELECT COUNT(*) FROM $indexing_table WHERE engine_type = %s",
                    $engine
                ));
                $rows = $wpdb->get_results($wpdb->prepare(
                    "SELECT * FROM $indexing_table WHERE engine_type = %s ORDER BY id DESC LIMIT %d OFFSET %d",
                    $engine, $per_page, $offset
                ), ARRAY_A);
            }
            
            wp_send_json_success(array(
                'rows' => $rows,
                'total' => intval($total),
                'pages' => ceil(($total ?: 0) / $per_page),
                'current_page' => $page
            ));
        }

        // 基础：检查单个URL的收录状态（启发式：是否有对应蜘蛛访问记录）
        
        public function details_page() {
            include WP_SPIDER_MONITOR_PLUGIN_PATH . 'templates/details-page.php';
        }
        
        public function push_page() {
            include WP_SPIDER_MONITOR_PLUGIN_PATH . 'templates/push-page.php';
        }
        
        public function indexing_page() {
            include WP_SPIDER_MONITOR_PLUGIN_PATH . 'templates/indexing-page.php';
        }
        
        public function records_page() {
            include WP_SPIDER_MONITOR_PLUGIN_PATH . 'templates/records-management.php';
        }
        
        
        /**
         * 为升级PRO版菜单添加金色字体样式
         */
        public function add_pro_menu_style() {
            ?>
            <style>
                /* 定位升级PRO版子菜单并设置金色字体 */
                #adminmenu li a[href="admin.php?page=spider-license"] {
                    color: #FFD700 !important;
                    font-weight: bold !important;
                    text-shadow: 0 0 3px rgba(255, 215, 0, 0.5) !important;
                    position: relative;
                }
                
                /* 悬停状态保持金色并增强效果 */
                #adminmenu li a[href="admin.php?page=spider-license"]:hover {
                    color: #FFC107 !important;
                    text-shadow: 0 0 5px rgba(255, 193, 7, 0.7) !important;
                    background: linear-gradient(135deg, rgba(255, 215, 0, 0.1), rgba(255, 193, 7, 0.1)) !important;
                }
                
                /* 当前页面状态 */
                #adminmenu li.current a[href="admin.php?page=spider-license"] {
                    color: #FFD700 !important;
                    background: linear-gradient(135deg, rgba(255, 215, 0, 0.15), rgba(255, 193, 7, 0.15)) !important;
                    border-left: 3px solid #FFD700 !important;
                }
                
                /* 添加金色光晕效果 */
                #adminmenu li a[href="admin.php?page=spider-license"]:before {
                    content: "✨";
                    margin-right: 5px;
                    font-size: 12px;
                    opacity: 0.8;
                }
                
                /* 响应式设计 */
                @media (max-width: 782px) {
                    #adminmenu li a[href="admin.php?page=spider-license"] {
                        color: #FFD700 !important;
                        font-weight: bold !important;
                    }
                }
            </style>
            <?php
        }
        
        
        // 新的付费验证系统：每次打开页面向远程服务端校验授权
        private $license_is_active = null;

        public function is_premium_version() {
            // 暂时全部免费：直接视为已激活
            return true;
        }

        // 统一父级菜单高亮
        public function filter_parent_file($parent_file) {
            $page = isset($_GET['page']) ? sanitize_text_field($_GET['page']) : '';
            // 所有本插件页面都归属于 wp-spider-monitor
            $plugin_pages = array(
                'wp-spider-monitor',
                'wp-spider-monitor-details',
                'wp-spider-monitor-settings-hub',
                'wp-spider-monitor-push',
                'wp-spider-monitor-indexing',
                'wp-spider-monitor-settings',
                'spider-license'
            );
            if (in_array($page, $plugin_pages, true)) {
                return 'wp-spider-monitor';
            }
            return $parent_file;
        }

        // 统一子菜单高亮
        public function filter_submenu_file($submenu_file) {
            $page = isset($_GET['page']) ? sanitize_text_field($_GET['page']) : '';
            switch ($page) {
                case 'wp-spider-monitor':
                    return 'wp-spider-monitor';
                case 'wp-spider-monitor-details':
                    return 'wp-spider-monitor-details';
                case 'wp-spider-monitor-settings-hub':
                    return 'wp-spider-monitor-settings-hub';
                case 'wp-spider-monitor-push':
                    return 'wp-spider-monitor-push';
                case 'wp-spider-monitor-indexing':
                    return 'wp-spider-monitor-indexing';
                case 'wp-spider-monitor-settings':
                    return 'wp-spider-monitor-settings';
                case 'spider-license':
                    // 许可证页也作为本插件子菜单一部分高亮
                    return 'spider-license';
            }
            return $submenu_file;
        }

        private function verify_remote_license() {
            // 简单缓存一次，避免同一请求内多次请求远程
            if ($this->license_is_active !== null) {
                return (bool) $this->license_is_active;
            }
            // 读取激活码（应在你的许可证设置页保存）
            $license_key = get_option('wp_spider_license_key', '');
            $verify_url  = get_option('wp_spider_license_verify_url', 'https://zibovip.top/api/spider/verify');
            $domain      = wp_parse_url(site_url(), PHP_URL_HOST);

            if (empty($license_key) || empty($verify_url)) {
                $this->license_is_active = false;
                return false;
            }

            // 可选签名
            $body = array(
                'license_key' => $license_key,
                'domain'      => $domain,
                'plugin'      => 'wp-spider-monitor'
            );
            $secret = get_option('spider_license_shared_secret');
            $body['ts'] = time();
            $body['nonce'] = wp_generate_password(8, false);
            if (!empty($secret)) {
                ksort($body);
                $body['sig'] = hash_hmac('sha256', http_build_query($body, '', '&', PHP_QUERY_RFC3986), $secret);
            }

            $response = wp_remote_post($verify_url, array(
                'timeout' => 10,
                'headers' => array('Content-Type' => 'application/x-www-form-urlencoded; charset=UTF-8'),
                'body'    => $body
            ));

            if (is_wp_error($response)) {
                $this->license_is_active = false;
                return false;
            }

            $code = wp_remote_retrieve_response_code($response);
            $body = wp_remote_retrieve_body($response);
            if ($code !== 200) {
                $this->license_is_active = false;
                return false;
            }

            $data = json_decode(trim($body), true);
            // 期望远程返回格式：{"success":true, "active":true}
            $is_active = (is_array($data) && !empty($data['success']) && (
                !empty($data['active']) || (!empty($data['status']) && $data['status']==='active') ||
                (!empty($data['activation']['status']) && $data['activation']['status']==='active')
            ));
            if (defined('WP_DEBUG') && WP_DEBUG) {
                $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '';
                error_log('[SpiderMonitor] verify_remote_license domain=' . $domain . ' host=' . $host . ' active=' . ($is_active ? 'true' : 'false') . ' response=' . (is_string($body) ? substr($body, 0, 500) : '')); 
            }
            if ($is_active) {
                $this->license_is_active = true;
                return true;
            }
            $this->license_is_active = false;
            return false;
        }
        
        public function ajax_check_premium() {
            // 检查nonce验证
            if (!wp_verify_nonce($_POST['nonce'] ?? '', 'wp_spider_monitor_nonce')) {
                wp_send_json_error('安全验证失败，请刷新页面重试');
                return;
            }
            
            // 检查用户权限
            if (!is_user_logged_in()) {
                wp_send_json_error('请先登录');
                return;
            }
            
            // 统一使用订阅客户端检查激活状态
            $is_premium = true;
            $license_info = null;
            
            // 暂时全部免费：不做远程与本地验证
            
            wp_send_json_success(array(
                'is_premium' => $is_premium,
                'plan' => 'pro',
                'features' => array(
                    'export_data' => $is_premium,
                    'clear_data' => $is_premium,
                    'real_time_update' => $is_premium,
                    'advanced_stats' => $is_premium,
                    'multi_site' => $is_premium,
                    'api_access' => $is_premium
                ),
                'license_info' => $license_info
            ));
        }
        
        public function ajax_upgrade_premium() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_die('权限不足');
            }
            
            // 暂时全部免费：不提供升级跳转
            wp_send_json_success(array(
                'message' => '所有功能已免费开放'
            ));
        }
        
        /**
         * 诊断激活状态问题
         */
        public function ajax_diagnose_activation() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            if (isset($GLOBALS['spider_subscription_client'])) {
                $diagnosis = $GLOBALS['spider_subscription_client']->diagnose_activation_issues();
                wp_send_json_success($diagnosis);
            } else {
                wp_send_json_error('订阅客户端未初始化');
            }
        }
        
        /**
         * 修复激活状态
         */
        public function ajax_fix_activation() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            if (isset($GLOBALS['spider_subscription_client'])) {
                $fixed = $GLOBALS['spider_subscription_client']->fix_activation_status();
                // 激活修复成功后，立即刷新远程令牌
                if ($fixed) {
                    if (class_exists('WP_Spider_Remote_Auth')) {
                        \WP_Spider_Remote_Auth::refresh_token_now('general', 'general');
                    }
                }
                wp_send_json_success(array(
                    'fixed' => $fixed,
                    'message' => $fixed ? '激活状态已修复' : '修复失败，请检查许可证'
                ));
            } else {
                wp_send_json_error('订阅客户端未初始化');
            }
        }
        
        private function get_premium_features() {
            return array(
                'export_data' => array(
                    'name' => '数据导出',
                    'description' => '导出蜘蛛访问统计数据',
                    'free' => false,
                    'premium' => true
                ),
                'clear_data' => array(
                    'name' => '清理数据',
                    'description' => '清理旧的蜘蛛访问数据',
                    'free' => false,
                    'premium' => true
                ),
                'real_time_update' => array(
                    'name' => '实时更新',
                    'description' => '实时数据更新和通知',
                    'free' => false,
                    'premium' => true
                ),
                'advanced_stats' => array(
                    'name' => '高级统计',
                    'description' => '详细的数据分析报告',
                    'free' => false,
                    'premium' => true
                ),
                'multi_site' => array(
                    'name' => '多站点支持',
                    'description' => '支持多站点网络',
                    'free' => false,
                    'premium' => true
                ),
                'api_access' => array(
                    'name' => 'API接口',
                    'description' => 'RESTful API访问权限',
                    'free' => false,
                    'premium' => true
                )
            );
        }
        
        public function check_feature_access($feature) {
            // 统一使用订阅客户端检查激活状态
            if (isset($GLOBALS['spider_subscription_client'])) {
                // 先同步激活状态，然后检查
                $GLOBALS['spider_subscription_client']->sync_activation_status();
                return $GLOBALS['spider_subscription_client']->is_activated();
            }
            
            // 备用检查：使用安全模块（存在时），否则回退 true（具体入口再强制令牌）
            if (function_exists('wp_spider_premium_security')) {
                $security = wp_spider_premium_security();
                return $security->is_premium_activated();
            }
            return true;
        }
        
        /**
         * 检查是否为付费用户
         */
        public function is_premium_user() {
            return $this->is_premium_version();
        }
        
        /**
         * 获取许可证页面URL
         */
        public function get_license_page_url() {
            return admin_url('admin.php?page=spider-license');
        }
        
        /**
         * 生成付费功能提示HTML
         */
        public function get_premium_tooltip($feature_name = '此功能') {
            $license_url = $this->get_license_page_url();
            return sprintf(
                '<div class="premium-tooltip" data-feature="%s">
                    <span class="premium-icon">🔒</span>
                    <span class="premium-text">%s需要激活许可证</span>
                    <a href="%s" class="premium-link">立即激活</a>
                </div>',
                esc_attr($feature_name),
                esc_html($feature_name),
                esc_url($license_url)
            );
        }
        
        // 监控蜘蛛访问
        public function monitor_spider_visits() {
            $user_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
            
            if (empty($user_agent)) {
                error_log("Spider Monitor: No user agent found");
                return;
            }
            
            error_log("Spider Monitor: User agent detected: " . $user_agent);
            
            $spider_name = $this->identify_spider($user_agent);
            
            error_log("Spider Monitor: Identified spider: " . ($spider_name ?: 'None'));
            
            if ($spider_name) {
                // 根据规则决定记录/标记
                $rule = $this->get_spider_rule($spider_name);
                error_log("Spider Monitor: Rule for $spider_name: $rule");
                $this->record_spider_visit($spider_name, $user_agent, $rule);
            }
        }
        
        // 识别蜘蛛类型
        private function identify_spider($user_agent) {
            $spider_patterns = array(
                'Googlebot' => '/Googlebot/i',
                'Bingbot' => '/bingbot/i',
                'Slurp' => '/Slurp/i',
                'DuckDuckBot' => '/DuckDuckBot/i',
                'Baiduspider' => '/Baiduspider/i',
                'YandexBot' => '/YandexBot/i',
                'facebookexternalhit' => '/facebookexternalhit/i',
                'Twitterbot' => '/Twitterbot/i',
                'LinkedInBot' => '/LinkedInBot/i',
                'WhatsApp' => '/WhatsApp/i',
                'Applebot' => '/Applebot/i',
                'SemrushBot' => '/SemrushBot/i',
                'AhrefsBot' => '/AhrefsBot/i',
                'MJ12bot' => '/MJ12bot/i',
                'DotBot' => '/DotBot/i',
                'SeoCheckBot' => '/SeoCheckBot/i',
                'BLEXBot' => '/BLEXBot/i',
                'ia_archiver' => '/ia_archiver/i',
                'archive.org_bot' => '/archive.org_bot/i',
                'Wayback Machine' => '/Wayback Machine/i'
            );
            // 常见新UA补充
            $spider_patterns['petalbot'] = '/PetalBot/i';
            $spider_patterns['bytespider'] = '/ByteSpider/i';
            $spider_patterns['seznambot'] = '/SeznamBot/i';
            $spider_patterns['naverbot'] = '/Naverbot|Yeti/i';
            $spider_patterns['sistrix'] = '/SISTRIX/i';
            $spider_patterns['moz'] = '/rogerbot|DotBot/i';
            $spider_patterns['uptimerobot'] = '/UptimeRobot/i';
            
            // 补充中国主要搜索引擎
            $spider_patterns['Sogou'] = '/Sogou|sogou/i';
            $spider_patterns['360Spider'] = '/360Spider|360spider/i';
            $spider_patterns['Shenma'] = '/Shenma|shenma/i';  // 神马搜索
            
            // 补充其他重要搜索引擎
            $spider_patterns['BingPreview'] = '/BingPreview/i';
            $spider_patterns['GoogleOther'] = '/GoogleOther|Google-InspectionTool/i';
            $spider_patterns['BingbotMobile'] = '/Bingbot-Mobile/i';
            $spider_patterns['GooglebotMobile'] = '/Googlebot-Mobile/i';
            $spider_patterns['GooglebotImage'] = '/Googlebot-Image/i';
            $spider_patterns['GooglebotNews'] = '/Googlebot-News/i';
            $spider_patterns['GooglebotVideo'] = '/Googlebot-Video/i';
            
            // 补充其他国际搜索引擎
            $spider_patterns['QwantBot'] = '/QwantBot/i';
            $spider_patterns['CCBot'] = '/CCBot/i';  // Common Crawl
            $spider_patterns['ia_archiver'] = '/ia_archiver/i';
            
            foreach ($spider_patterns as $name => $pattern) {
                if (preg_match($pattern, $user_agent)) {
                    return $name;
                }
            }
            // 兜底：对未知但含有bot/spider关键词的UA也记录为 UnknownBot
            if (preg_match('/bot|crawler|spider/i', $user_agent)) {
                return 'UnknownBot';
            }
            return false;
        }

        // 识别bot类型
        private function identify_bot_type($user_agent, $spider_name) {
            $bot_types = array(
                'search_engine' => [
                    'Googlebot', 'Bingbot', 'Baiduspider', 'YandexBot', 'DuckDuckBot',
                    'Sogou', '360Spider', 'Shenma', 'PetalBot', 'ByteSpider',
                    'BingPreview', 'GoogleOther', 'BingbotMobile', 'GooglebotMobile',
                    'GooglebotImage', 'GooglebotNews', 'GooglebotVideo', 'QwantBot'
                ],
                'social_media' => [
                    'facebookexternalhit', 'Twitterbot', 'LinkedInBot', 'WhatsApp'
                ],
                'seo_tools' => [
                    'SemrushBot', 'AhrefsBot', 'MJ12bot', 'DotBot', 'SeoCheckBot', 'BLEXBot'
                ],
                'archive' => [
                    'ia_archiver', 'archive.org_bot', 'Wayback Machine'
                ],
                'apple' => [
                    'Applebot'
                ],
                'yahoo' => [
                    'Slurp'
                ]
            );

            foreach ($bot_types as $type => $spiders) {
                if (in_array($spider_name, $spiders)) {
                    return $type;
                }
            }

            // 根据user_agent进一步分析
            if (preg_match('/bot|crawler|spider/i', $user_agent)) {
                if (preg_match('/search|index/i', $user_agent)) {
                    return 'search_engine';
                } elseif (preg_match('/social|share/i', $user_agent)) {
                    return 'social_media';
                } elseif (preg_match('/seo|marketing/i', $user_agent)) {
                    return 'seo_tools';
                } elseif (preg_match('/archive|backup/i', $user_agent)) {
                    return 'archive';
                } else {
                    return 'unknown_bot';
                }
            }

            return 'unknown';
        }
        
        // 识别URL类型
        private function identify_url_type($url) {
            $parsed_url = parse_url($url);
            $path = $parsed_url['path'] ?? '';
            
            // 默认URL类型规则
            $url_rules = array(
                'home' => array('^/$', '^/index\.php$', '^/index\.php\?'),
                'post' => array('/?p=', '/post/'),
                'page' => array('/page/'),
                'category' => array('/category/'),
                'tag' => array('/tag/'),
                'author' => array('/author/'),
                'search' => array('/?s=', '/search/'),
                'feed' => array('/feed/', '/rss/', '/atom/'),
                'sitemap' => array('/sitemap', '/robots.txt'),
                'api' => array('/wp-json/', '/api/'),
                'admin' => array('/wp-admin/', '/wp-login.php'),
                'attachment' => array('/wp-content/uploads/')
            );
            
            foreach ($url_rules as $type => $patterns) {
                foreach ($patterns as $pattern) {
                    // 检查是否为正则表达式模式（以^开头）
                    if (strpos($pattern, '^') === 0) {
                        if (preg_match('/' . $pattern . '/', $path) || preg_match('/' . $pattern . '/', $url)) {
                            return $type;
                        }
                    } else {
                        // 使用字符串匹配
                        if (strpos($path, $pattern) !== false || strpos($url, $pattern) !== false) {
                            return $type;
                        }
                    }
                }
            }
            
            // 检查是否为文章页面
            if (function_exists('url_to_postid')) {
                $post_id = url_to_postid($url);
                if ($post_id > 0) {
                    $post_type = get_post_type($post_id);
                    if ($post_type === 'post') {
                        return 'post';
                    } elseif ($post_type === 'page') {
                        return 'page';
                    }
                }
            }
            
            return 'other';
        }
        
        // 从URL获取文章ID
        private function get_post_id_from_url($url) {
            if (function_exists('url_to_postid')) {
                return url_to_postid($url);
            }
            return 0;
        }
        
        // 检查是否为伪蜘蛛
        private function is_fake_bot($spider_name, $ip_address, $user_agent) {
            // 检查IP是否在已知的搜索引擎IP段中
            $known_spider_ips = array(
                'Googlebot' => array('66.249.', '64.233.', '72.14.', '74.125.', '209.85.'),
                'Bingbot' => array('157.55.', '207.46.', '40.77.'),
                'Baiduspider' => array('180.76.', '123.125.', '220.181.'),
                'YandexBot' => array('77.88.', '5.255.', '87.250.'),
            );
            
            if (isset($known_spider_ips[$spider_name])) {
                foreach ($known_spider_ips[$spider_name] as $ip_prefix) {
                    if (strpos($ip_address, $ip_prefix) === 0) {
                        return false; // 真实蜘蛛
                    }
                }
                return true; // 可能是伪蜘蛛
            }
            
            // 检查User-Agent是否包含可疑特征
            $suspicious_patterns = array(
                '/bot.*bot/i',  // 重复bot关键词
                '/crawler.*crawler/i',  // 重复crawler关键词
                '/spider.*spider/i',  // 重复spider关键词
            );
            
            foreach ($suspicious_patterns as $pattern) {
                if (preg_match($pattern, $user_agent)) {
                    return true;
                }
            }
            
            return false;
        }
        
        // 获取伪蜘蛛原因
        private function get_fake_bot_reason($spider_name, $ip_address, $user_agent) {
            $reasons = array();
            
            // 检查IP段
            $known_spider_ips = array(
                'Googlebot' => array('66.249.', '64.233.', '72.14.', '74.125.', '209.85.'),
                'Bingbot' => array('157.55.', '207.46.', '40.77.'),
                'Baiduspider' => array('180.76.', '123.125.', '220.181.'),
            );
            
            if (isset($known_spider_ips[$spider_name])) {
                $is_valid_ip = false;
                foreach ($known_spider_ips[$spider_name] as $ip_prefix) {
                    if (strpos($ip_address, $ip_prefix) === 0) {
                        $is_valid_ip = true;
                        break;
                    }
                }
                if (!$is_valid_ip) {
                    $reasons[] = 'IP地址不在官方IP段内';
                }
            }
            
            // 检查User-Agent格式
            if (preg_match('/bot.*bot/i', $user_agent)) {
                $reasons[] = 'User-Agent格式异常';
            }
            
            return implode('; ', $reasons);
        }
        
        // 记录蜘蛛访问
        private function record_spider_visit($spider_name, $user_agent, $rule = 'normal') {
            global $wpdb;
            
            $visits_table = $wpdb->prefix . 'spider_visits';
            $stats_table = $wpdb->prefix . 'spider_stats';
            
            $ip_address = $this->get_client_ip();
            // 暂时禁用 hostname 查询，避免 DNS 查询阻塞数据写入
            $hostname = '';
            $url = home_url($_SERVER['REQUEST_URI']);
            $referer = $_SERVER['HTTP_REFERER'] ?? '';
            $response_code = http_response_code();
            $response_time = $this->get_response_time();
            $page_title = $this->get_page_title();
            $bot_type = $this->identify_bot_type($user_agent, $spider_name);
            
            // 识别URL类型和文章ID
            $url_type = $this->identify_url_type($url);
            $post_id = $this->get_post_id_from_url($url);
            
            // 检查是否为伪蜘蛛
            $is_fake_bot = $this->is_fake_bot($spider_name, $ip_address, $user_agent);
            $fake_reason = $is_fake_bot ? $this->get_fake_bot_reason($spider_name, $ip_address, $user_agent) : '';
            
            // 调试：记录准备插入的数据
            $insert_data = array(
                'spider_name' => $spider_name,
                'bot_type' => $bot_type,
                'user_agent' => $user_agent,
                'ip_address' => $ip_address,
                'url' => $url,
                'referer' => $referer,
                'response_code' => $response_code,
                'response_time' => $response_time,
                'page_title' => $page_title,
                'is_blocked' => $rule === 'blocked' ? 1 : 0,
                'is_ignored' => $rule === 'ignored' ? 1 : 0,
                'rule_tag' => $rule,
                'hostname' => $hostname,
                'is_verified_bot' => $this->verify_bot($spider_name, $user_agent, $ip_address) ? 1 : 0,
                'verified_source' => 'rdns',
                'url_type' => $url_type,
                'post_id' => $post_id,
                'is_fake_bot' => $is_fake_bot ? 1 : 0,
                'fake_reason' => $fake_reason
            );
            
            error_log("Spider Monitor: Attempting to insert data: " . print_r($insert_data, true));
            
            // 记录访问详情
            $insert_result = $wpdb->insert(
                $visits_table,
                $insert_data,
                array('%s', '%s', '%s', '%s', '%s', '%s', '%d', '%f', '%s', '%d', '%d', '%s', '%s', '%d', '%s', '%s', '%d', '%d', '%s')
            );
            
            // 调试：记录插入结果
            if ($insert_result === false) {
                error_log("Spider Monitor: Failed to insert into visits table. Error: " . $wpdb->last_error);
                error_log("Spider Monitor: Last query: " . $wpdb->last_query);
            } else {
                error_log("Spider Monitor: Successfully inserted record with ID: " . $wpdb->insert_id);
            }
            
            // 拦截的记录不计入统计
            // 注释掉 stats 表更新，以 visits 表为准
            // if ($rule !== 'blocked') {
            //     $this->update_spider_stats($spider_name, $url, $response_time);
            // }

            // 更新URL聚合统计
            $this->update_url_stats($url, $response_code, $response_time, $spider_name);
        }

        // 规则存取
        private function get_spider_rule($spider_name) {
            $rules = get_option('wp_spider_rules', array());
            return isset($rules[$spider_name]) ? $rules[$spider_name] : 'normal';
        }

        private function set_spider_rule($spider_name, $rule) {
            $allowed = array('normal', 'ignored', 'blocked');
            if (!in_array($rule, $allowed)) { $rule = 'normal'; }
            $rules = get_option('wp_spider_rules', array());
            $rules[$spider_name] = $rule;
            update_option('wp_spider_rules', $rules);
            return $rule;
        }

        public function ajax_spider_set_rule() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            if (!current_user_can('manage_options')) { wp_send_json_error('权限不足'); }
            
            // 令牌强校验
            $this->require_token('spider_management', 'general');
            
            $spider = sanitize_text_field($_POST['spider'] ?? '');
            $rule = sanitize_text_field($_POST['rule'] ?? 'normal');
            if (empty($spider)) { wp_send_json_error('参数为空'); }
            $saved = $this->set_spider_rule($spider, $rule);
            wp_send_json_success(array('spider' => $spider, 'rule' => $saved));
        }
        
        // 获取客户端IP
        private function get_client_ip() {
            $ip_keys = array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR');
            foreach ($ip_keys as $key) {
                if (array_key_exists($key, $_SERVER) === true) {
                    foreach (explode(',', $_SERVER[$key]) as $ip) {
                        $ip = trim($ip);
                        if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false) {
                            return $ip;
                        }
                    }
                }
            }
            return $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
        }
        
        // 获取响应时间
        private function get_response_time() {
            if (defined('WP_START_TIMESTAMP')) {
                return microtime(true) - WP_START_TIMESTAMP;
            }
            return 0;
        }
        
        // 获取页面标题
        private function get_page_title() {
            if (is_singular()) {
                return get_the_title();
            } elseif (is_home()) {
                return get_bloginfo('name');
            } elseif (is_category()) {
                return single_cat_title('', false);
            } elseif (is_tag()) {
                return single_tag_title('', false);
            } elseif (is_archive()) {
                return get_the_archive_title();
            }
            return '';
        }
        
        // 更新蜘蛛统计
        private function update_spider_stats($spider_name, $url, $response_time) {
            global $wpdb;
            
            $stats_table = $wpdb->prefix . 'spider_stats';
            $today = current_time('Y-m-d');
            
            // 检查今日是否已有记录
            $existing = $wpdb->get_row($wpdb->prepare(
                "SELECT * FROM $stats_table WHERE spider_name = %s AND visit_date = %s",
                $spider_name, $today
            ));
            
            if ($existing) {
                // 更新现有记录
                $wpdb->update(
                    $stats_table,
                    array(
                        'visit_count' => $existing->visit_count + 1,
                        'unique_pages' => $this->get_unique_pages_count($spider_name, $today),
                        'total_response_time' => $existing->total_response_time + $response_time,
                        'avg_response_time' => ($existing->total_response_time + $response_time) / ($existing->visit_count + 1),
                        'last_visit' => current_time('mysql')
                    ),
                    array('id' => $existing->id),
                    array('%d', '%d', '%f', '%f', '%s'),
                    array('%d')
                );
            } else {
                // 创建新记录
                $wpdb->insert(
                    $stats_table,
                    array(
                        'spider_name' => $spider_name,
                        'visit_date' => $today,
                        'visit_count' => 1,
                        'unique_pages' => 1,
                        'total_response_time' => $response_time,
                        'avg_response_time' => $response_time,
                        'last_visit' => current_time('mysql')
                    ),
                    array('%s', '%s', '%d', '%d', '%f', '%f', '%s')
                );
            }
        }
        
        // 获取唯一页面数量
        private function get_unique_pages_count($spider_name, $date) {
            global $wpdb;
            
            $visits_table = $wpdb->prefix . 'spider_visits';
            return $wpdb->get_var($wpdb->prepare(
                "SELECT COUNT(DISTINCT url) FROM $visits_table WHERE spider_name = %s AND DATE(visit_time) = %s",
                $spider_name, $date
            ));
        }

        // 更新URL聚合统计
        private function update_url_stats($url, $status_code, $response_time, $spider_name) {
            global $wpdb;
            $table = $wpdb->prefix . 'spider_url_stats';
            $post_id = url_to_postid($url);

            $existing = $wpdb->get_row($wpdb->prepare("SELECT * FROM $table WHERE url = %s", $url));
            if ($existing) {
                $new_count = intval($existing->visit_count) + 1;
                $new_avg = ($existing->avg_response_time * $existing->visit_count + $response_time) / max(1, $new_count);
                $wpdb->update(
                    $table,
                    array(
                        'post_id' => $post_id,
                        'last_visit' => current_time('mysql'),
                        'visit_count' => $new_count,
                        'last_status' => $status_code,
                        'avg_response_time' => $new_avg,
                        'last_spider' => $spider_name
                    ),
                    array('id' => $existing->id)
                );
            } else {
                $wpdb->insert(
                    $table,
                    array(
                        'url' => $url,
                        'post_id' => $post_id,
                        'last_visit' => current_time('mysql'),
                        'visit_count' => 1,
                        'last_status' => $status_code,
                        'avg_response_time' => $response_time,
                        'last_spider' => $spider_name
                    )
                );
            }
        }
        
        // AJAX获取每日统计
        public function ajax_get_daily_stats() {
            // 确保这是一个AJAX请求
            if (!defined('DOING_AJAX') || !DOING_AJAX) {
                return;
            }
            
            // 设置正确的内容类型
            header('Content-Type: application/json; charset=utf-8');
            
            try {
                check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
                
                if (!current_user_can('manage_options')) {
                    wp_send_json_error('权限不足');
                    return;
                }
                
                $days = intval($_POST['days'] ?? 1);
                // 使用北京时区计算当前日期与小时，并生成当天/昨天的本地起止时间
                try {
                    $tz = new \DateTimeZone('Asia/Shanghai');
                    $nowCn = new \DateTimeImmutable('now', $tz);
                    $current_date = $nowCn->format('Y-m-d');
                    $current_hour = intval($nowCn->format('G'));
                    $previous_date = $nowCn->sub(new \DateInterval('P1D'))->format('Y-m-d');
                    $today_start = $nowCn->setTime(0, 0, 0)->format('Y-m-d H:i:s');
                    $today_end = $nowCn->setTime(23, 59, 59)->format('Y-m-d H:i:s');
                    $yesterday_start = $nowCn->sub(new \DateInterval('P1D'))->setTime(0, 0, 0)->format('Y-m-d H:i:s');
                    $yesterday_end = $nowCn->sub(new \DateInterval('P1D'))->setTime(23, 59, 59)->format('Y-m-d H:i:s');
                } catch (\Exception $e) {
                    // 兜底：回退到WordPress站点时区
                    $current_date = current_time('Y-m-d');
                    $current_hour = intval(current_time('H'));
                    $previous_date = date('Y-m-d', strtotime('-1 day', strtotime($current_date)));
                    $today_start = $current_date . ' 00:00:00';
                    $today_end = $current_date . ' 23:59:59';
                    $yesterday_start = date('Y-m-d 00:00:00', strtotime('-1 day', strtotime($current_date)));
                    $yesterday_end = date('Y-m-d 23:59:59', strtotime('-1 day', strtotime($current_date)));
                }
                
                global $wpdb;
                $visits_table = $wpdb->prefix . 'spider_visits';
                
                // 检查表是否存在
                if ($wpdb->get_var("SHOW TABLES LIKE '$visits_table'") != $visits_table) {
                    wp_send_json_success(array(
                        'hourly_stats' => array(),
                        'previous_hourly_stats' => array(),
                        'unique_pages' => 0,
                        'total_spiders' => 0,
                        'total_visits' => 0,
                        'current_hour' => $current_hour,
                        'date' => $current_date,
                        'previous_date' => $previous_date,
                        'message' => '数据表不存在，请先创建数据表'
                    ));
                    return;
                }
                
                // 只从 spider_visits 表获取小时级数据
                $results = $wpdb->get_results($wpdb->prepare(
                    "SELECT 
                        spider_name,
                        HOUR(visit_time + INTERVAL 8 HOUR) as hour,
                        COUNT(*) as visit_count
                    FROM $visits_table 
                    WHERE DATE(visit_time + INTERVAL 8 HOUR) = %s AND HOUR(visit_time + INTERVAL 8 HOUR) <= %s
                    GROUP BY spider_name, HOUR(visit_time + INTERVAL 8 HOUR)
                    ORDER BY spider_name, hour",
                    $current_date, $current_hour
                ), ARRAY_A);
                
                // 重新组织数据结构 - 当前数据
                $hourly_stats = array();
                foreach ($results as $row) {
                    $spider_name = $row['spider_name'];
                    $hour = intval($row['hour']);
                    $count = intval($row['visit_count']);
                    
                    if (!isset($hourly_stats[$spider_name])) {
                        $hourly_stats[$spider_name] = array();
                    }
                    $hourly_stats[$spider_name][$hour] = $count;
                }
                
                // 只从 spider_visits 表获取昨日小时级数据
                $previous_results = $wpdb->get_results($wpdb->prepare(
                    "SELECT 
                        spider_name,
                        HOUR(visit_time + INTERVAL 8 HOUR) as hour,
                        COUNT(*) as visit_count
                    FROM $visits_table 
                    WHERE DATE(visit_time + INTERVAL 8 HOUR) = %s AND HOUR(visit_time + INTERVAL 8 HOUR) <= %s
                    GROUP BY spider_name, HOUR(visit_time + INTERVAL 8 HOUR)
                    ORDER BY spider_name, hour",
                    $previous_date, $current_hour
                ), ARRAY_A);
                
                // 重新组织数据结构 - 昨日数据
                $previous_hourly_stats = array();
                foreach ($previous_results as $row) {
                    $spider_name = $row['spider_name'];
                    $hour = intval($row['hour']);
                    $count = intval($row['visit_count']);
                    
                    if (!isset($previous_hourly_stats[$spider_name])) {
                        $previous_hourly_stats[$spider_name] = array();
                    }
                    $previous_hourly_stats[$spider_name][$hour] = $count;
                }
                
                // 只从 spider_visits 表获取统计数据
                $unique_pages = $wpdb->get_var($wpdb->prepare(
                    "SELECT COUNT(DISTINCT url) FROM $visits_table WHERE DATE(visit_time + INTERVAL 8 HOUR) = %s AND HOUR(visit_time + INTERVAL 8 HOUR) <= %s",
                    $current_date, $current_hour
                ));
                
                $total_visits = $wpdb->get_var($wpdb->prepare(
                    "SELECT COUNT(*) FROM $visits_table WHERE DATE(visit_time + INTERVAL 8 HOUR) = %s AND HOUR(visit_time + INTERVAL 8 HOUR) <= %s",
                    $current_date, $current_hour
                ));
                
                wp_send_json_success(array(
                    'hourly_stats' => $hourly_stats,
                    'previous_hourly_stats' => $previous_hourly_stats,
                    'unique_pages' => intval($unique_pages),
                    'total_spiders' => count($hourly_stats),
                    'total_visits' => intval($total_visits),
                    'current_hour' => $current_hour,
                    'date' => $current_date,
                    'previous_date' => $previous_date
                ));
                
            } catch (Exception $e) {
                wp_send_json_error('数据加载失败: ' . $e->getMessage());
            }
            
            wp_die(); // 确保AJAX请求正确结束
        }
        
        // 测试函数：手动插入一条测试记录
        public function ajax_test_insert() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_die('权限不足');
            }
            
            global $wpdb;
            $visits_table = $wpdb->prefix . 'spider_visits';
            
            // 插入一条测试记录
            $test_data = array(
                'spider_name' => 'TestBot',
                'bot_type' => 'test',
                'user_agent' => 'TestBot/1.0 (Test)',
                'ip_address' => '127.0.0.1',
                'url' => home_url('/test'),
                'referer' => '',
                'response_code' => 200,
                'response_time' => 0.123,
                'page_title' => 'Test Page',
                'is_blocked' => 0,
                'is_ignored' => 0,
                'rule_tag' => 'normal',
                'hostname' => '',
                'is_verified_bot' => 0,
                'verified_source' => 'test'
            );
            
            $result = $wpdb->insert(
                $visits_table,
                $test_data,
                array('%s', '%s', '%s', '%s', '%s', '%s', '%d', '%f', '%s', '%d', '%d', '%s', '%s', '%d', '%s')
            );
            
            if ($result === false) {
                wp_send_json_error('插入失败: ' . $wpdb->last_error);
            } else {
                wp_send_json_success('插入成功，ID: ' . $wpdb->insert_id);
            }
        }
        
        // AJAX获取蜘蛛详情
        public function ajax_get_spider_details() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_die('权限不足');
            }
            
            $spider_name = sanitize_text_field($_POST['spider_name']);
            $date = sanitize_text_field($_POST['date'] ?? current_time('Y-m-d'));
            
            global $wpdb;
            $visits_table = $wpdb->prefix . 'spider_visits';
            
            // 从 visits 表计算统计数据
            $result = $wpdb->get_row($wpdb->prepare(
                "SELECT 
                    spider_name,
                    COUNT(*) as visit_count,
                    COUNT(DISTINCT url) as unique_pages,
                    AVG(response_time) as avg_response_time,
                    MIN(visit_time) as first_visit,
                    MAX(visit_time) as last_visit
                FROM $visits_table 
                WHERE spider_name = %s AND DATE(visit_time + INTERVAL 8 HOUR) = %s
                GROUP BY spider_name",
                $spider_name, $date
            ), ARRAY_A);
            
            wp_send_json_success($result);
        }
        
        // 新增：获取蜘蛛今日统计信息的AJAX处理函数
        public function ajax_get_spider_today_stats() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_die('权限不足');
            }
            
            $spider_name = sanitize_text_field($_POST['spider_name']);
            if (empty($spider_name)) {
                wp_send_json_error('蜘蛛名称不能为空');
            }
            
            global $wpdb;
            
            // 获取今日数据
            $today = current_time('Y-m-d');
            
            // 查询今日该蜘蛛的统计
            $spider_stats = $wpdb->get_row($wpdb->prepare(
                "SELECT COUNT(*) as visit_count, COUNT(DISTINCT url) as unique_pages, AVG(response_time) as avg_response_time
                FROM {$wpdb->prefix}spider_visits 
                WHERE spider_name = %s AND DATE(visit_time) = %s",
                $spider_name, $today
            ));
            
            // 获取bot类型信息
            $bot_type = $wpdb->get_var($wpdb->prepare(
                "SELECT bot_type FROM {$wpdb->prefix}spider_visits 
                WHERE spider_name = %s AND bot_type IS NOT NULL 
                ORDER BY visit_time DESC LIMIT 1",
                $spider_name
            ));
            
            // 构建详情页URL
            $details_url = admin_url('admin.php?page=spider-details&spider=' . urlencode($spider_name));
            
            $data = array(
                'spider_name' => $spider_name,
                'visit_count' => (int)($spider_stats->visit_count || 0),
                'unique_pages' => (int)($spider_stats->unique_pages || 0),
                'avg_response_time' => round((float)($spider_stats->avg_response_time || 0), 2),
                'bot_type' => $bot_type ? $bot_type : 'unknown',
                'details_url' => $details_url
            );
            
            wp_send_json_success($data);
        }
        
        // AJAX获取蜘蛛访问的URL
        public function ajax_get_spider_urls() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_die('权限不足');
            }
            
            $spider_name = sanitize_text_field($_POST['spider_name']);
            $date = sanitize_text_field($_POST['date'] ?? current_time('Y-m-d'));
            $page = intval($_POST['page'] ?? 1);
            $per_page = 20;
            $offset = ($page - 1) * $per_page;
            
            global $wpdb;
            $visits_table = $wpdb->prefix . 'spider_visits';
            
            $results = $wpdb->get_results($wpdb->prepare(
                "SELECT url, page_title, visit_time, response_code, response_time 
                FROM $visits_table 
                WHERE spider_name = %s AND DATE(visit_time) = %s 
                ORDER BY visit_time DESC 
                LIMIT %d OFFSET %d",
                $spider_name, $date, $per_page, $offset
            ), ARRAY_A);
            
            $total = $wpdb->get_var($wpdb->prepare(
                "SELECT COUNT(*) FROM $visits_table WHERE spider_name = %s AND DATE(visit_time) = %s",
                $spider_name, $date
            ));
            
            wp_send_json_success(array(
                'urls' => $results,
                'total' => $total,
                'pages' => ceil($total / $per_page),
                'current_page' => $page
            ));
        }
        
        // AJAX导出统计
        public function ajax_export_stats() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_die('权限不足');
            }
            
            // 令牌强校验（导出属于付费管理操作）
            $this->require_token('export_data', 'general');
            
            $format = sanitize_text_field($_POST['format'] ?? 'csv');
            $date = sanitize_text_field($_POST['date'] ?? current_time('Y-m-d'));
            
            global $wpdb;
            $visits_table = $wpdb->prefix . 'spider_visits';
            
            // 从 visits 表计算统计数据
            $results = $wpdb->get_results($wpdb->prepare(
                "SELECT 
                    spider_name,
                    COUNT(*) as visit_count,
                    COUNT(DISTINCT url) as unique_pages,
                    AVG(response_time) as avg_response_time,
                    MIN(visit_time) as first_visit,
                    MAX(visit_time) as last_visit
                FROM $visits_table 
                WHERE DATE(visit_time + INTERVAL 8 HOUR) = %s
                GROUP BY spider_name
                ORDER BY visit_count DESC",
                $date
            ), ARRAY_A);
            
            if ($format === 'csv') {
                $this->export_csv($results, 'spider-stats-' . $date);
            } elseif ($format === 'json') {
                $this->export_json($results, 'spider-stats-' . $date);
            }
        }
        
        // AJAX清理旧数据
        public function ajax_clear_old_visits() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_die('权限不足');
            }
            
            // 令牌强校验（清理属于付费管理操作）
            $this->require_token('clear_data', 'general');
            
            $days = intval($_POST['days'] ?? 30);
            
            global $wpdb;
            $visits_table = $wpdb->prefix . 'spider_visits';
            
            $deleted_visits = $wpdb->query($wpdb->prepare(
                "DELETE FROM $visits_table WHERE visit_time < %s",
                date('Y-m-d H:i:s', strtotime("-{$days} days"))
            ));
            
            wp_send_json_success(array(
                'deleted_visits' => $deleted_visits,
                'message' => '已清理 ' . $deleted_visits . ' 条访问记录'
            ));
        }

        public function ajax_manual_push_url() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            $url = sanitize_text_field($_POST['url']);
            
            if (!filter_var($url, FILTER_VALIDATE_URL)) {
                wp_send_json_error('无效的URL格式');
            }
            
            $results = $this->push_url_to_engines($url);
            wp_send_json_success($results);
        }
        
        public function ajax_add_custom_engine() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            $engine_name = sanitize_text_field($_POST['engine_name']);
            $api_url = sanitize_text_field($_POST['api_url']);
            $api_key = sanitize_text_field($_POST['api_key']);
            $push_method = sanitize_text_field($_POST['push_method']);
            
            if (empty($engine_name) || empty($api_url)) {
                wp_send_json_error('搜索引擎名称和API接口不能为空');
            }
            
            global $wpdb;
            $table_name = $wpdb->prefix . 'spider_push_config';
            
            // 检查是否已存在
            $exists = $wpdb->get_var($wpdb->prepare(
                "SELECT COUNT(*) FROM $table_name WHERE engine_name = %s",
                $engine_name
            ));
            
            if ($exists > 0) {
                wp_send_json_error('该搜索引擎名称已存在');
            }
            
            $result = $wpdb->insert($table_name, array(
                'engine_name' => $engine_name,
                'api_url' => $api_url,
                'api_key' => $api_key,
                'site_url' => get_site_url(),
                'push_method' => $push_method,
                'is_active' => 0,
                'is_system' => 0,
                'engine_type' => 'custom'
            ));
            
            if ($result) {
                wp_send_json_success(array(
                    'id' => $wpdb->insert_id,
                    'message' => '搜索引擎添加成功'
                ));
            } else {
                wp_send_json_error('添加失败，请重试');
            }
        }
        
        public function ajax_delete_engine() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            $engine_id = intval($_POST['engine_id']);
            
            global $wpdb;
            $table_name = $wpdb->prefix . 'spider_push_config';
            
            // 检查是否为系统引擎
            $engine = $wpdb->get_row($wpdb->prepare(
                "SELECT * FROM $table_name WHERE id = %d",
                $engine_id
            ));
            
            if (!$engine) {
                wp_send_json_error('搜索引擎不存在');
            }
            
            if ($engine->is_system) {
                wp_send_json_error('系统默认搜索引擎不能删除');
            }
            
            $result = $wpdb->delete($table_name, array('id' => $engine_id));
            
            if ($result) {
                wp_send_json_success('搜索引擎删除成功');
            } else {
                wp_send_json_error('删除失败，请重试');
            }
        }
        
        public function ajax_get_engines() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            global $wpdb;
            $table_name = $wpdb->prefix . 'spider_push_config';
            
            $engines = $wpdb->get_results("SELECT * FROM $table_name ORDER BY engine_name");
            
            wp_send_json_success($engines);
        }

        // 保存五大搜索引擎的启用与token
        public function ajax_save_push_config() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            if (!current_user_can('manage_options')) { wp_send_json_error('权限不足'); }
            $config = isset($_POST['config']) ? (array) $_POST['config'] : array();
            if (empty($config)) { wp_send_json_error('无配置'); }
            global $wpdb;
            $table = $wpdb->prefix . 'spider_push_config';
            $allowed = array('baidu','bing','google','360','bytedance');
            foreach ($allowed as $type) {
                $row = isset($config[$type]) ? (array)$config[$type] : array();
                $enabled = isset($row['enabled']) ? intval($row['enabled']) : 0;
                $token = isset($row['token']) ? sanitize_text_field($row['token']) : '';
                // 统一保存到 site_token 字段，api_key作兼容；若不存在系统行则插入
                $updated = $wpdb->update(
                    $table,
                    array('is_active' => $enabled, 'site_token' => $token, 'api_key' => $token, 'updated_time' => current_time('mysql')),
                    array('engine_type' => $type, 'is_system' => 1),
                    array('%d','%s','%s','%s'),
                    array('%s','%d')
                );
                if ($updated === 0) {
                    $exists = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM $table WHERE engine_type = %s AND is_system = 1", $type));
                    if (intval($exists) === 0) {
                        $wpdb->insert(
                            $table,
                            array(
                                'engine_name' => $this->get_engine_name_by_type($type),
                                'engine_type' => $type,
                                'api_url' => '',
                                'api_key' => $token,
                                'site_url' => get_site_url(),
                                'site_token' => $token,
                                'is_active' => $enabled,
                                'is_system' => 1,
                                'created_time' => current_time('mysql'),
                                'updated_time' => current_time('mysql')
                            )
                        );
                    }
                }
            }
            wp_send_json_success('配置已保存');
        }
        
        // AJAX手动创建数据库表
        public function ajax_create_tables() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_die('权限不足');
            }
            
            try {
                $this->create_tables();
                
                // 验证表是否创建成功
                global $wpdb;
                $visits_table = $wpdb->prefix . 'spider_visits';
                $stats_table = $wpdb->prefix . 'spider_stats';
                
                $visits_exists = $wpdb->get_var("SHOW TABLES LIKE '$visits_table'") == $visits_table;
                $stats_exists = $wpdb->get_var("SHOW TABLES LIKE '$stats_table'") == $stats_table;
                
                if ($visits_exists && $stats_exists) {
                    wp_send_json_success('数据库表创建成功！');
                } else {
                    wp_send_json_error('数据库表创建失败，请检查数据库权限');
                }
            } catch (Exception $e) {
                wp_send_json_error('创建数据库表时出错：' . $e->getMessage());
            }
        }

        // AJAX保存主题偏好 - 保存到设置中
        public function ajax_save_theme_preference() {
            // 确保这是一个AJAX请求
            if (!defined('DOING_AJAX') || !DOING_AJAX) {
                return;
            }
            
            // 设置正确的内容类型
            header('Content-Type: application/json; charset=utf-8');
            
            try {
                // 检查nonce验证
                if (!wp_verify_nonce($_POST['nonce'] ?? '', 'wp_spider_monitor_nonce')) {
                    wp_send_json_error('安全验证失败，请刷新页面重试');
                    return;
                }
                
                // 检查用户权限 - 需要管理员权限才能修改设置
                if (!current_user_can('manage_options')) {
                    wp_send_json_error('权限不足');
                    return;
                }
                
                $theme = sanitize_text_field($_POST['theme'] ?? 'modern');
                $valid_themes = array('modern', 'classic', 'minimal', 'dark', 'colorful', 'vibrant', 'cyberpunk', 'nature');
                
                if (!in_array($theme, $valid_themes)) {
                    $theme = 'modern';
                }
                
                // 保存到设置中
                $settings = get_option('wp_spider_monitor_settings', array());
                $settings['interface_theme'] = $theme;
                update_option('wp_spider_monitor_settings', $settings);
                
                wp_send_json_success(array(
                    'theme' => $theme,
                    'message' => '主题设置已保存'
                ));
                
            } catch (Exception $e) {
                wp_send_json_error('保存主题设置失败: ' . $e->getMessage());
            }
            
            wp_die(); // 确保AJAX请求正确结束
        }
        
        // 获取全局主题设置
        public function ajax_get_user_theme() {
            // 检查nonce验证
            if (!wp_verify_nonce($_POST['nonce'] ?? '', 'wp_spider_monitor_nonce')) {
                wp_send_json_error('安全验证失败');
                return;
            }
            
            // 检查用户权限
            if (!is_user_logged_in()) {
                wp_send_json_error('请先登录');
                return;
            }
            
            $theme = $this->get_user_theme();
            
            wp_send_json_success(array(
                'theme' => $theme
            ));
        }
        
        // 获取全局主题设置
        private function get_user_theme($user_id = null) {
            // 从设置中获取主题，不再按用户存储
            $settings = get_option('wp_spider_monitor_settings', array());
            $theme = isset($settings['interface_theme']) ? $settings['interface_theme'] : 'modern';
            
            // 打印调试信息到浏览器控制台
            echo '<script>';
            echo 'console.log("🎯 WP Spider Monitor - 数据库主题检查:");';
            echo 'console.log("📊 wp_spider_monitor_settings:", ' . json_encode($settings) . ');';
            echo 'console.log("🎨 interface_theme:", "' . esc_js($theme) . '");';
            echo '</script>';
            
            // 如果还没有设置主题，尝试从旧的用户主题表中迁移
            if ($theme === 'modern') {
                global $wpdb;
                $user_theme_table = $wpdb->prefix . 'spider_user_theme';
                
                // 检查表是否存在
                if ($wpdb->get_var("SHOW TABLES LIKE '$user_theme_table'") == $user_theme_table) {
                    // 获取第一个用户的主题作为全局主题
                    $old_theme = $wpdb->get_var("SELECT theme_name FROM $user_theme_table ORDER BY id ASC LIMIT 1");
                    if ($old_theme) {
                        $settings['interface_theme'] = $old_theme;
                        update_option('wp_spider_monitor_settings', $settings);
                        $theme = $old_theme;
                        echo '<script>console.log("🔄 从旧表迁移主题:", "' . esc_js($old_theme) . '");</script>';
                    }
                }
            }
            
            echo '<script>console.log("✅ 最终返回主题:", "' . esc_js($theme) . '");</script>';
            return $theme ?: 'modern'; // 如果没有设置，返回默认主题
        }

        public function ajax_create_spider_tables() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_die('权限不足');
            }
            
            try {
                $this->create_tables();
                
                // 验证表是否创建成功
                global $wpdb;
                $visits_table = $wpdb->prefix . 'spider_visits';
                $stats_table = $wpdb->prefix . 'spider_stats';
                
                $visits_exists = $wpdb->get_var("SHOW TABLES LIKE '$visits_table'") == $visits_table;
                $stats_exists = $wpdb->get_var("SHOW TABLES LIKE '$stats_table'") == $stats_table;
                
                if ($visits_exists && $stats_exists) {
                    wp_send_json_success('数据表创建成功');
                } else {
                    wp_send_json_error('数据表创建失败，请检查数据库权限');
                }
            } catch (Exception $e) {
                wp_send_json_error('创建数据库表时出错：' . $e->getMessage());
            }
        }

        public function ajax_export_spider_data() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_die('权限不足');
            }
            
            global $wpdb;
            $visits_table = $wpdb->prefix . 'spider_visits';
            
            $data = $wpdb->get_results("SELECT * FROM $visits_table ORDER BY visit_time DESC");
            
            if (empty($data)) {
                wp_die('暂无数据可导出');
            }

            // 设置CSV头
            header('Content-Type: text/csv; charset=utf-8');
            header('Content-Disposition: attachment; filename=spider-data-' . date('Y-m-d') . '.csv');
            
            $output = fopen('php://output', 'w');
            fprintf($output, chr(0xEF).chr(0xBB).chr(0xBF)); // BOM for UTF-8
            
            // 写入CSV头
            fputcsv($output, array('ID', '蜘蛛名称', 'User Agent', 'IP地址', 'URL', 'Referer', '访问时间', '状态码', '响应时间', '页面标题'));
            
            // 写入数据
            foreach ($data as $row) {
                fputcsv($output, array(
                    $row->id,
                    $row->spider_name,
                    $row->user_agent,
                    $row->ip_address,
                    $row->url,
                    $row->referer,
                    $row->visit_time,
                    $row->response_code,
                    $row->response_time,
                    $row->page_title
                ));
            }
            
            fclose($output);
            exit;
        }

        public function ajax_clear_spider_data() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_die('权限不足');
            }
            
            global $wpdb;
            $visits_table = $wpdb->prefix . 'spider_visits';
            
            // 清空表数据
            $wpdb->query("TRUNCATE TABLE $visits_table");
            
            wp_send_json_success('数据清理完成');
        }
        
        /**
         * 推送URL到搜索引擎
         */
        public function push_url_to_engines($url_or_post_id) {
            if (is_numeric($url_or_post_id)) {
                $post_id = $url_or_post_id;
                $post = get_post($post_id);
                if (!$post || $post->post_status != 'publish' || $post->post_type != 'post') {
                    return false;
                }
                $url = get_permalink($post_id);
            } else {
                $url = $url_or_post_id;
            }
            
            if (!filter_var($url, FILTER_VALIDATE_URL)) {
                return false;
            }
            
            // 包含搜索引擎推送API
            require_once plugin_dir_path(__FILE__) . 'includes/search-engine-push-apis.php';
            
            $engines = $this->get_configured_engines();
            $results = array();
            $site_url = get_site_url();
            
            foreach ($engines as $engine) {
                if ($engine['is_active'] && !empty($engine['site_token'])) {
                    $engine_type = $engine['engine_type'];
                    $token = !empty($engine['site_token']) ? $engine['site_token'] : ($engine['api_key'] ?? '');
                    
                    try {
                        switch ($engine_type) {
                            case 'baidu':
                                $result = SearchEnginePushAPI::push_to_baidu(array($url), $site_url, $token);
                                break;
                            case 'bing':
                                $result = SearchEnginePushAPI::push_to_bing(array($url), $site_url, $token);
                                break;
                            case '360':
                                $result = SearchEnginePushAPI::push_to_360(array($url), $site_url, $token);
                                break;
                            case 'bytedance':
                                $result = SearchEnginePushAPI::push_to_bytedance(array($url), $site_url, $token);
                                break;
                            case 'google':
                                $result = SearchEnginePushAPI::push_to_google(array($url), $site_url, $token);
                                break;
                            default:
                                continue 2;
                        }
                        
                        $results[$engine_type] = $result;
                        
                        // 记录推送日志
                        $this->log_push_attempt($url, $engine_type, $result);
                        
                    } catch (Exception $e) {
                        $results[$engine_type] = array(
                            'error' => $e->getMessage(),
                            'engine' => $engine_type
                        );
                    }
                }
            }
            
            return $results;
        }
        
        /**
         * 批量推送URL
         */
        public function push_urls_to_engines($urls) {
            if (!is_array($urls)) {
                $urls = array($urls);
            }
            
            // 过滤有效URL
            $valid_urls = array();
            foreach ($urls as $url) {
                if (filter_var($url, FILTER_VALIDATE_URL)) {
                    $valid_urls[] = $url;
                }
            }
            
            if (empty($valid_urls)) {
                return false;
            }
            
            // 包含搜索引擎推送API
            require_once plugin_dir_path(__FILE__) . 'includes/search-engine-push-apis.php';
            
            $engines = $this->get_configured_engines();
            $results = array();
            $site_url = get_site_url();
            
            foreach ($engines as $engine) {
                if ($engine['is_active'] && !empty($engine['site_token'])) {
                    $engine_type = $engine['engine_type'];
                    $token = !empty($engine['site_token']) ? $engine['site_token'] : ($engine['api_key'] ?? '');
                    
                    try {
                        switch ($engine_type) {
                            case 'baidu':
                                $result = SearchEnginePushAPI::push_to_baidu($valid_urls, $site_url, $token);
                                break;
                            case 'bing':
                                $result = SearchEnginePushAPI::push_to_bing($valid_urls, $site_url, $token);
                                break;
                            case '360':
                                $result = SearchEnginePushAPI::push_to_360($valid_urls, $site_url, $token);
                                break;
                            case 'bytedance':
                                $result = SearchEnginePushAPI::push_to_bytedance($valid_urls, $site_url, $token);
                                break;
                            case 'google':
                                $result = SearchEnginePushAPI::push_to_google($valid_urls, $site_url, $token);
                                break;
                            default:
                                continue 2;
                        }
                        
                        $results[$engine_type] = $result;
                        
                        // 记录推送日志
                        foreach ($valid_urls as $url) {
                            $this->log_push_attempt($url, $engine_type, $result);
                        }
                        
                    } catch (Exception $e) {
                        $results[$engine_type] = array(
                            'error' => $e->getMessage(),
                            'engine' => $engine_type
                        );
                    }
                }
            }
            
            return $results;
        }
        
        /**
         * 记录推送日志
         */
        private function log_push_attempt($url, $engine, $result) {
            global $wpdb;
            
            $log_table = $wpdb->prefix . 'spider_push_log';
            $post_id = url_to_postid($url);
            
            $wpdb->insert($log_table, array(
                'url' => $url,
                'post_id' => $post_id,
                'engine_name' => $engine,
                'response_data' => is_array($result) ? json_encode($result) : strval($result),
                'response_code' => isset($result['status']) ? $result['status'] : 0,
                'status' => isset($result['error']) ? 'failed' : 'success',
                'ip_address' => $this->get_client_ip(),
                'created_time' => current_time('mysql')
            ));
        }
        
        /**
         * 新文章发布时自动推送
         */
        public function auto_push_on_publish($post_id) {
            if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
                return;
            }
            
            $post = get_post($post_id);
            if (!$post || $post->post_status != 'publish' || $post->post_type != 'post') {
                return;
            }
            
            // 检查是否已推送
            $pushed = get_post_meta($post_id, '_wp_spider_pushed', true);
            if ($pushed) {
                return;
            }
            
            // 延迟推送，避免发布时冲突
            wp_schedule_single_event(time() + 30, 'wp_spider_push_post', array($post_id));
        }
        
        /**
         * 处理延迟推送
         */
        public function handle_delayed_push($post_id) {
            $results = $this->push_url_to_engines($post_id);
            
            if ($results) {
                update_post_meta($post_id, '_wp_spider_pushed', 1);
                update_post_meta($post_id, '_wp_spider_push_results', $results);
            }
        }
        
        // 导出CSV
        private function export_csv($data, $filename) {
            header('Content-Type: text/csv; charset=utf-8');
            header('Content-Disposition: attachment; filename=' . $filename . '.csv');
            
            $output = fopen('php://output', 'w');
            fprintf($output, chr(0xEF).chr(0xBB).chr(0xBF)); // BOM for UTF-8
            
            if (!empty($data)) {
                fputcsv($output, array_keys($data[0]));
                foreach ($data as $row) {
                    fputcsv($output, $row);
                }
            }
            
            fclose($output);
            exit;
        }
        
        // 导出JSON
        private function export_json($data, $filename) {
            header('Content-Type: application/json; charset=utf-8');
            header('Content-Disposition: attachment; filename=' . $filename . '.json');
            
            echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
            exit;
        }
        
        /**
         * 测试所有引擎连接
         */
        public function ajax_test_all_engines() {
            check_ajax_referer('test_engines_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_die('权限不足');
            }
            
            $engines = $this->get_configured_engines();
            $results = array();
            
            foreach ($engines as $engine) {
                if ($engine['is_active'] && !empty($engine['site_token'])) {
                    $test_result = $this->test_engine_connection($engine['engine_type']);
                    $results[$engine['engine_type']] = array(
                        'name' => $engine['engine_name'],
                        'success' => $test_result['success'],
                        'message' => $test_result['message']
                    );
                }
            }
            
            $success_count = count(array_filter($results, function($r) { return $r['success']; }));
            $total_count = count($results);
            
            wp_send_json_success(array(
                'message' => sprintf('测试完成：%d/%d 个引擎连接成功', $success_count, $total_count),
                'results' => $results
            ));
        }

        // 错误状态分析（今日）
        public function ajax_spider_error_stats() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            if (!current_user_can('manage_options')) { wp_send_json_error('权限不足'); }
            global $wpdb;
            $today = current_time('Y-m-d');
            $visits = $wpdb->prefix . 'spider_visits';
            $rows = $wpdb->get_results($wpdb->prepare(
                "SELECT response_code, COUNT(*) as count FROM $visits WHERE DATE(visit_time) = %s GROUP BY response_code",
                $today
            ), ARRAY_A);
            wp_send_json_success($rows ?: array());
        }

        // 24小时热力图（高级功能）
        public function ajax_spider_heatmap_24h() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            if (!current_user_can('manage_options')) { wp_send_json_error('权限不足'); }
            // 热力图为付费功能，强制令牌，不随周期放行
            $this->require_token('heatmap_24h', 'general');
            global $wpdb;
            $today = current_time('Y-m-d');
            $visits = $wpdb->prefix . 'spider_visits';
            // 统计 每小时 x 蜘蛛 的访问次数
            $rows = $wpdb->get_results($wpdb->prepare(
                "SELECT spider_name, HOUR(visit_time) as hour, COUNT(*) as count FROM $visits WHERE DATE(visit_time) = %s GROUP BY spider_name, HOUR(visit_time)",
                $today
            ), ARRAY_A);
            wp_send_json_success($rows ?: array());
        }

        // 付费：来源占比（示例）
        public function ajax_spider_sources_premium() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            if (!current_user_can('manage_options')) { wp_send_json_error('权限不足'); }
            // 来源占比为付费功能，强制令牌，不随周期放行
            $this->require_token('sources_premium', 'general');
            global $wpdb;
            $visits = $wpdb->prefix . 'spider_visits';
            $today = current_time('Y-m-d');
            $rows = $wpdb->get_results($wpdb->prepare(
                "SELECT spider_name, COUNT(*) as cnt FROM $visits WHERE DATE(visit_time)=%s GROUP BY spider_name ORDER BY cnt DESC LIMIT 10",
                $today
            ), ARRAY_A);
            wp_send_json_success($rows ?: array());
        }
        
        /**
         * 测试单个引擎连接
         */
        private function test_engine_connection($engine_type) {
            $engine = $this->get_engine_config($engine_type);
            if (!$engine || empty($engine['site_token'])) {
                return array('success' => false, 'message' => '未配置token');
            }
            
            // 这里可以添加实际的连接测试逻辑
            return array('success' => true, 'message' => '配置正确');
        }
        
        // 蜘蛛概况相关AJAX处理函数
        
        /**
         * 获取蜘蛛概况统计数据
         */
        public function ajax_get_overview_stats() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            global $wpdb;
            $visits_table = $wpdb->prefix . 'spider_visits';
            
            $today = current_time('Y-m-d');
            $yesterday = date('Y-m-d', strtotime('-1 day'));
            $month_start = date('Y-m-d', strtotime('-30 days'));
            
            // 今日数据
            $today_stats = $wpdb->get_row($wpdb->prepare(
                "SELECT 
                    COUNT(DISTINCT spider_name) as spider_count,
                    COUNT(*) as url_count,
                    COUNT(*) / COUNT(DISTINCT spider_name) as avg_urls
                FROM $visits_table 
                WHERE DATE(visit_time) = %s AND is_ignored = 0",
                $today
            ), ARRAY_A);
            
            // 昨日数据
            $yesterday_stats = $wpdb->get_row($wpdb->prepare(
                "SELECT 
                    COUNT(DISTINCT spider_name) as spider_count,
                    COUNT(*) as url_count,
                    COUNT(*) / COUNT(DISTINCT spider_name) as avg_urls
                FROM $visits_table 
                WHERE DATE(visit_time) = %s AND is_ignored = 0",
                $yesterday
            ), ARRAY_A);
            
            // 30天平均数据 - 令牌治理（soft gate，不中断整体响应）
            $monthly_stats = null;
            $monthly_allowed = false;
            if (!function_exists('wp_spider_secure_license_verification')) {
                $monthly_allowed = false;
            } else {
                // 尝试通过令牌
                require_once plugin_dir_path(__FILE__) . 'includes/remote-auth.php';
                $enf = WP_Spider_Remote_Auth::enforce_token('monthly_overview', 'month');
                $monthly_allowed = is_array($enf) && !empty($enf['success']);
            }
            if ($monthly_allowed) {
                $monthly_stats = $wpdb->get_row($wpdb->prepare(
                    "SELECT 
                        COUNT(DISTINCT spider_name) / 30 as spider_count,
                        COUNT(*) / 30 as url_count,
                        COUNT(*) / COUNT(DISTINCT spider_name) as avg_urls
                    FROM $visits_table 
                    WHERE DATE(visit_time) >= %s AND is_ignored = 0",
                    $month_start
                ), ARRAY_A);
            }
            
            wp_send_json_success(array(
                'today' => $today_stats ?: array('spider_count' => 0, 'url_count' => 0, 'avg_urls' => 0),
                'yesterday' => $yesterday_stats ?: array('spider_count' => 0, 'url_count' => 0, 'avg_urls' => 0),
                'monthly' => $monthly_allowed && $monthly_stats ? $monthly_stats : array('spider_count' => 0, 'url_count' => 0, 'avg_urls' => 0),
                'is_premium' => $monthly_allowed,
                'premium_message' => $monthly_allowed ? '' : '30天平均功能需要有效访问令牌（PRO）',
                'upgrade_url' => admin_url('admin.php?page=spider-license')
            ));
        }
        
        /**
         * 获取趋势图数据
         */
        public function ajax_get_trend_data() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            $period = sanitize_text_field($_POST['period'] ?? 'today');
            $show_comparison = sanitize_text_field($_POST['show_comparison'] ?? 'false') === 'true';
            $chart_type = sanitize_text_field($_POST['chart_type'] ?? 'trend');

            // 响应时间分析：所有时间范围均需令牌（包括今天/昨天）
            if ($chart_type === 'response_time') {
                $this->require_token('response_time_analysis', 'general');
            }
            
            // 今天/昨天免费：直接返回数据（但响应时间分析已在上方强制令牌）
            if (in_array($period, array('today', 'yesterday'), true)) {
                try {
                    $labels = $this->generate_hourly_labels();
                    $hourly = $this->get_hourly_trend_data($period);
                    $details = $this->get_spider_details_by_hour($period);
                    
                    // 组装前端期望的结构：hourly_stats = { spiderName: { hour: count } }
                    $hourly_stats = array();
                    $total_visits = 0;
                    foreach ($details as $hour => $items) {
                        if (!is_array($items)) { continue; }
                        foreach ($items as $it) {
                            $name = isset($it['name']) ? $it['name'] : 'Unknown';
                            $cnt = intval($it['count'] ?? 0);
                            if (!isset($hourly_stats[$name])) { $hourly_stats[$name] = array(); }
                            $hourly_stats[$name][intval($hour)] = $cnt;
                            $total_visits += $cnt;
                        }
                    }
                    
                    // 兼容 spider-overview.php 的 renderTrendChart 所需结构
                    // today: 使用 $hourly 中每小时的 spider_count 与 visit_count
                    $today = array();
                    foreach ($hourly as $row) {
                        $today[] = array(
                            'spider_count' => intval($row['spider_count'] ?? 0),
                            'visit_count' => intval($row['visit_count'] ?? 0)
                        );
                    }
                    // yesterday: 如果 period= today 则取昨天数据；如果本身是 yesterday 则给空数组即可
                    $yesterday = array();
                    if ($period === 'today') {
                        $y_details = $this->get_spider_details_by_hour('yesterday');
                        $y_hourly  = $this->get_hourly_trend_data('yesterday');
                        foreach ($y_hourly as $row) {
                            $yesterday[] = array(
                                'spider_count' => intval($row['spider_count'] ?? 0),
                                'visit_count' => intval($row['visit_count'] ?? 0)
                            );
                        }
                        // 用昨天详情替换 spider_details_yesterday（仅内部使用，不强制返回）
                        $spider_details_yesterday = $y_details;
                    }
                    
                    // spider_details: 每小时的 [{name,count}]，直接用已计算的 $details
                    $spider_details = array();
                    for ($i = 0; $i < 24; $i++) {
                        $spider_details[$i] = isset($details[$i]) && is_array($details[$i]) ? array_values($details[$i]) : array();
                    }
                    
                    // 统计 unique_pages（简化为当日去重URL数）
                    global $wpdb; $visits_table = $wpdb->prefix . 'spider_visits';
                    $dateExpr = $period === 'today' ? 'CURDATE()' : 'DATE_SUB(CURDATE(), INTERVAL 1 DAY)';
                    $unique_pages = intval($wpdb->get_var("SELECT COUNT(DISTINCT url) FROM $visits_table WHERE DATE(visit_time) = $dateExpr AND is_ignored = 0"));
                    
                    $response = array(
                        // 供 assets/admin.js 使用
                        'labels' => $labels,
                        'hourly_stats' => $hourly_stats,
                        'current_hour' => intval(current_time('H')),
                        'unique_pages' => $unique_pages,
                        'total_visits' => $total_visits,
                        'period' => $period,
                        // 供 templates/spider-overview.php 使用
                        'today' => $today,
                        'yesterday' => $yesterday,
                        'spider_details' => $spider_details
                    );
                    wp_send_json_success($response);
                } catch (Exception $e) {
                    wp_send_json_error('数据加载失败: ' . $e->getMessage());
                }
            }
            
            // 其他周期保持授权校验
            require_once plugin_dir_path(__FILE__) . 'includes/remote-auth.php';
            $license_key = get_option('spider_license_key');
            $auth = WP_Spider_Remote_Auth::check('trend', $period, $license_key);
            if (!is_array($auth) || !$auth['success']) {
                wp_send_json_error(array(
                    'message' => $auth['message'] ?? '7天和30天数据查看需要激活PRO版本',
                    'upgrade_url' => $auth['upgrade_url'] ?? admin_url('admin.php?page=spider-license')
                ));
            }
            $token = $auth['token'] ?? null;
            if (function_exists('wp_spider_secure_license_verification')) {
                $verification = wp_spider_secure_license_verification();
                $access = $verification->verify_feature_access('trend', $period, $license_key, $token);
                if (!is_array($access) || !$access['success']) {
                    wp_send_json_error(array(
                        'message' => $access['message'] ?? '7天和30天数据查看需要激活PRO版本',
                        'upgrade_url' => $access['upgrade_url'] ?? admin_url('admin.php?page=spider-license')
                    ));
                }
            }
            // 暂无周/月的统计实现，返回提示（保持前端可处理）
            wp_send_json_error(array('message' => '该时间范围统计即将上线')); 
        }
        
        /**
         * 服务端授权验证 - 蜘蛛访问趋势无需验证，响应时间分析需要验证
         */
        private function verify_server_authorization($chart_type, $period) {
            // 全局：今天/昨天免费
            if (in_array($period, array('today', 'yesterday'), true)) {
                return array(
                    'success' => true,
                    'message' => 'free access (today/yesterday)'
                );
            }
            // 蜘蛛访问趋势：7天/30天需远程授权校验（不可仅前端绕过）
            if ($chart_type === 'trend') {
                // 令牌驱动的远程授权（统一入口）+ 本地缓存
                require_once plugin_dir_path(__FILE__) . 'includes/remote-auth.php';
                $license_key = get_option('spider_license_key');
                $auth = WP_Spider_Remote_Auth::check('trend', $period, $license_key);
                if (!is_array($auth) || !$auth['success']) {
                    return array(
                        'success' => false,
                        'message' => $auth['message'] ?? '7天和30天数据查看需要激活PRO版本',
                        'upgrade_url' => $auth['upgrade_url'] ?? admin_url('admin.php?page=spider-license')
                    );
                }
                $token = $auth['token'] ?? null;
                // 二次安全验证（抗简单篡改）：统一的安全许可证模块（含令牌验证）
                if (function_exists('wp_spider_secure_license_verification')) {
                    $verification = wp_spider_secure_license_verification();
                    $access = $verification->verify_feature_access('trend', $period, $license_key, $token);
                    if (!is_array($access) || !$access['success']) {
                        return array(
                            'success' => false,
                            'message' => $access['message'] ?? '7天和30天数据查看需要激活PRO版本',
                            'upgrade_url' => $access['upgrade_url'] ?? admin_url('admin.php?page=spider-license')
                        );
                    }
                }
                return array('success' => true, 'message' => '授权验证成功');
            }
            // 响应时间分析：所有时间范围（包括今天/昨天）都需要远程验证（不使用本地校验）
            if ($chart_type === 'response_time') {
                // 令牌强校验（不享受 today/yesterday 放行）
                $this->require_token('response_time_analysis', 'general');
                // 获取硬件指纹
                $hardware_fingerprint = $this->get_hardware_fingerprint();
                
                // 获取域名信息
                $domain = home_url();
                $site_url = get_site_url();
                
                // 生成请求签名
                $timestamp = time();
                $nonce = wp_generate_password(16, false);
                $signature = $this->generate_request_signature($chart_type, $period, $timestamp, $nonce, $hardware_fingerprint);
                
                // 准备验证数据
                $auth_data = array(
                    'chart_type' => $chart_type,
                    'period' => $period,
                    'domain' => $domain,
                    'site_url' => $site_url,
                    'hardware_fingerprint' => $hardware_fingerprint,
                    'timestamp' => $timestamp,
                    'nonce' => $nonce,
                    'signature' => $signature,
                    // 传递客户端站点密钥，供服务端参与签名校验
                    'secret_key' => $this->get_encryption_key(),
                    'plugin_version' => defined('WP_SPIDER_MONITOR_VERSION') ? WP_SPIDER_MONITOR_VERSION : '2.0.0',
                    'wp_version' => get_bloginfo('version'),
                    'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
                    'server_ip' => $_SERVER['SERVER_ADDR'] ?? '',
                    'request_id' => uniqid('spider_auth_', true)
                );
                
                // 向授权服务器发送验证请求
                $response = $this->send_auth_request($auth_data);
                
                if (!$response || !is_array($response)) {
                    return array(
                        'success' => false,
                        'message' => '无法连接到授权服务器，请在许可证设置中配置授权服务器地址或检查网络',
                        'upgrade_url' => admin_url('admin.php?page=spider-license')
                    );
                }
                
                // 简化模式：只有返回包含签名时才进行校验
                if (isset($response['signature']) && !$this->verify_response_signature($response)) {
                    return array(
                        'success' => false,
                        'message' => '授权服务器响应验证失败，请联系技术支持或检查服务器时间同步',
                        'upgrade_url' => admin_url('admin.php?page=spider-license')
                    );
                }
                
                // 检查授权状态
                if (!$response['success']) {
                    return array(
                        'success' => false,
                        'message' => $response['message'] ?? '授权验证失败'
                    );
                }
                
                // 检查功能权限（兼容简化模式：features 可能是列表或缺省全开）
                $features = $response['features'] ?? [];
                $respTimeAllowed = true;
                if (is_array($features)) {
                    if (array_keys($features) === range(0, count($features) - 1)) {
                        // 索引数组：若未声明该项，则默认允许
                        $respTimeAllowed = in_array('response_time_analysis', $features, true) ? true : true;
                    } else {
                        // 关联数组：按布尔开关判断；未声明则默认允许
                        $respTimeAllowed = array_key_exists('response_time_analysis', $features) ? (bool)$features['response_time_analysis'] : true;
                    }
                }
                if (!$respTimeAllowed) {
                    return array(
                        'success' => false,
                        'message' => '响应时间分析功能需要激活PRO版本'
                    );
                }
                
                // 检查时间范围权限
                $extAllowed = true;
                if (is_array($features)) {
                    if (array_keys($features) === range(0, count($features) - 1)) {
                        // 索引数组未声明则默认允许
                        $extAllowed = in_array('extended_time_ranges', $features, true) ? true : true;
                    } else {
                        $extAllowed = array_key_exists('extended_time_ranges', $features) ? (bool)$features['extended_time_ranges'] : true;
                    }
                }
                if (in_array($period, array('week', 'month')) && !$extAllowed) {
                    return array(
                        'success' => false,
                        'message' => '7天和30天数据查看需要激活PRO版本'
                    );
                }
                
                return array(
                    'success' => true,
                    'message' => '授权验证成功',
                    'auth_data' => $response
                );
            }
            
            // 其他图表类型也统一走远程授权（简化模式），杜绝本地化判定
            require_once plugin_dir_path(__FILE__) . 'includes/remote-auth.php';
            $result = WP_Spider_Remote_Auth::check($chart_type, $period);
            if (!$result['success'] && isset($result['upgrade_url'])) {
                return array(
                    'success' => false,
                    'message' => $result['message'],
                    'upgrade_url' => $result['upgrade_url']
                );
            }
            if (!$result['success']) {
                return array('success' => false, 'message' => $result['message'] ?? '授权验证失败');
            }
            return array('success' => true, 'message' => '授权验证成功', 'auth_data' => $result['auth_data'] ?? []);
        }
        
        /**
         * 获取硬件指纹
         */
        private function get_hardware_fingerprint() {
            $fingerprint_data = array();
            
            // 获取服务器信息
            $fingerprint_data['server_software'] = $_SERVER['SERVER_SOFTWARE'] ?? '';
            $fingerprint_data['php_version'] = PHP_VERSION;
            $fingerprint_data['os'] = PHP_OS;
            
            // 获取WordPress信息
            $fingerprint_data['wp_version'] = get_bloginfo('version');
            $fingerprint_data['site_url'] = get_site_url();
            $fingerprint_data['admin_email'] = get_option('admin_email');
            
            // 获取数据库信息
            global $wpdb;
            $fingerprint_data['db_version'] = $wpdb->db_version();
            $fingerprint_data['db_charset'] = $wpdb->get_charset_collate();
            
            // 获取插件信息
            $fingerprint_data['plugin_version'] = defined('WP_SPIDER_MONITOR_VERSION') ? WP_SPIDER_MONITOR_VERSION : '2.0.0';
            
            // 获取服务器IP
            $fingerprint_data['server_ip'] = $_SERVER['SERVER_ADDR'] ?? '';
            $fingerprint_data['server_port'] = $_SERVER['SERVER_PORT'] ?? '';
            
            // 生成唯一指纹
            $fingerprint_string = serialize($fingerprint_data);
            return hash('sha256', $fingerprint_string . $this->get_encryption_key());
        }
        
        /**
         * 生成请求签名
         */
        private function generate_request_signature($chart_type, $period, $timestamp, $nonce, $hardware_fingerprint) {
            $signature_data = array(
                'chart_type' => $chart_type,
                'period' => $period,
                'timestamp' => $timestamp,
                'nonce' => $nonce,
                'hardware_fingerprint' => $hardware_fingerprint,
                'secret_key' => $this->get_encryption_key()
            );
            
            $signature_string = serialize($signature_data);
            return hash('sha256', $signature_string);
        }
        
        /**
         * 验证响应签名
         */
        private function verify_response_signature($response) {
            if (!isset($response['signature']) || !isset($response['timestamp'])) {
                return false;
            }
            
            // 检查时间戳（防止重放攻击，5分钟内有效）
            $current_time = time();
            $response_time = $response['timestamp'];
            if (abs($current_time - $response_time) > 300) {
                return false;
            }
            
            // 验证签名
            $expected_signature = hash('sha256', $response['timestamp'] . $this->get_encryption_key());
            return hash_equals($expected_signature, $response['signature']);
        }
        
        /**
         * 发送授权请求到服务器 - 强制加密验证
         */
        private function send_auth_request($auth_data) {
            // 使用固定的远程授权服务器（客户端硬编码）- 简化模式：直接传 license_key + domain
            $api_url = 'https://zibovip.top/dingyue/secure-license-verification.php';
            
            // 简化模式参数（无需加密）：license_key + domain + chart_type + period
            $license_key = get_option('spider_license_key');
            $request_body = array(
                'license_key' => $license_key,
                'domain' => home_url(),
                'chart_type' => $auth_data['chart_type'],
                'period' => $auth_data['period']
            );
            
            $args = array(
                'method' => 'POST',
                'timeout' => 45,
                'redirection' => 2,
                'httpversion' => '1.1',
                'blocking' => true,
                'headers' => array(
                    'Content-Type' => 'application/x-www-form-urlencoded',
                    'User-Agent' => 'Spider-Monitor-Client/' . (defined('WP_SPIDER_MONITOR_VERSION') ? WP_SPIDER_MONITOR_VERSION : '2.0.0'),
                    'X-Request-ID' => $auth_data['request_id'] ?? uniqid('spider_', true)
                ),
                'body' => http_build_query($request_body),
                // 某些服务器证书链不完整会导致验证失败，这里放宽校验以确保能连通
                'sslverify' => false
            );
            
            $response = wp_remote_post($api_url, $args);
            
            if (is_wp_error($response)) {
                $err = $response->get_error_message();
                error_log('[SpiderMonitor] Failed to send auth request: ' . $err);
                // 返回结构化错误，便于前端显示真实原因
                return array('success' => false, 'message' => '请求授权服务器失败：' . $err);
            }
            
            $response_code = wp_remote_retrieve_response_code($response);
            if ($response_code !== 200) {
                error_log('[SpiderMonitor] Auth server returned error code: ' . $response_code);
                return array('success' => false, 'message' => '授权服务器HTTP状态异常：' . $response_code);
            }
            
            $body = wp_remote_retrieve_body($response);
            // 去除可能的 BOM 和不可见字符
            if (function_exists('mb_convert_encoding')) {
                $body = preg_replace('/^\xEF\xBB\xBF/', '', $body);
            }
            $body = trim($body);
            $result = json_decode($body, true);
            
            if (!$result) {
                error_log('[SpiderMonitor] Failed to decode auth server response: ' . substr($body, 0, 200));
                // 返回一个带错误信息的数组，避免前端误判为"无法连接"
                return array(
                    'success' => false,
                    'message' => '授权服务器返回格式错误，请检查服务端输出是否为JSON'
                );
            }
            
            return $result;
        }
        
        /**
         * 加密授权数据 - 强制加密验证
         */
        private function encrypt_auth_data($data) {
            $public_key = $this->get_server_public_key();
            if (!$public_key) {
                // 如果无法获取公钥，记录错误并拒绝请求
                error_log('[SpiderMonitor] Failed to get server public key for encryption');
                return false;
            }
            
            $json_data = json_encode($data);
            if (!$json_data) {
                error_log('[SpiderMonitor] Failed to encode auth data to JSON');
                return false;
            }
            
            $encrypted = '';
            $success = openssl_public_encrypt($json_data, $encrypted, $public_key);
            
            if (!$success) {
                error_log('[SpiderMonitor] Failed to encrypt auth data with public key');
                return false;
            }
            
            return base64_encode($encrypted);
        }
        
        /**
         * 获取服务器公钥
         */
        private function get_server_public_key() {
            // 从缓存中获取公钥
            $cached_key = get_transient('spider_server_public_key');
            if ($cached_key) {
                return $cached_key;
            }
            
            // 从远程服务器获取公钥
            $response = wp_remote_get('https://zibovip.top/dingyue/get-public-key.php');
            if (is_wp_error($response)) {
                return false;
            }
            
            $body = wp_remote_retrieve_body($response);
            $result = json_decode($body, true);
            
            if ($result && isset($result['public_key'])) {
                // 缓存公钥1小时
                set_transient('spider_server_public_key', $result['public_key'], 3600);
                return $result['public_key'];
            }
            
            return false;
        }
        
        /**
         * 获取加密密钥
         */
        private function get_encryption_key() {
            $key = get_option('wp_spider_encryption_key');
            if (!$key) {
                $key = wp_generate_password(64, true, true);
                update_option('wp_spider_encryption_key', $key);
            }
            return $key;
        }
        
        /**
         * 获取按小时分组的趋势数据
         */
        private function get_hourly_trend_data($period) {
            global $wpdb;
            $visits_table = $wpdb->prefix . 'spider_visits';
            
            $date_condition = '';
            switch ($period) {
                case 'today':
                    $date_condition = "DATE(visit_time) = CURDATE()";
                    break;
                case 'yesterday':
                    $date_condition = "DATE(visit_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)";
                    break;
            }
            
            $data = $wpdb->get_results($wpdb->prepare(
                "SELECT 
                    HOUR(visit_time) as hour,
                    COUNT(DISTINCT spider_name) as spider_count,
                    COUNT(*) as visit_count
                FROM $visits_table 
                WHERE $date_condition AND is_ignored = 0
                GROUP BY HOUR(visit_time)
                ORDER BY hour ASC"
            ), ARRAY_A);
            
            // 生成完整的24小时数据，缺失的小时用0填充
            $hourly_data = array();
            for ($i = 0; $i < 24; $i++) {
                $hourly_data[$i] = array(
                    'hour' => $i,
                    'spider_count' => 0,
                    'visit_count' => 0
                );
            }
            
            // 填充实际数据
            foreach ($data as $item) {
                $hourly_data[$item['hour']] = $item;
            }
            
            return array_values($hourly_data);
        }
        
        /**
         * 生成小时标签
         */
        private function generate_hourly_labels() {
            $labels = array();
            for ($i = 0; $i < 24; $i++) {
                $labels[] = sprintf('%02d:00', $i);
            }
            return $labels;
        }
        
        /**
         * 获取每个小时的蜘蛛详情数据
         */
        private function get_spider_details_by_hour($period) {
            global $wpdb;
            $visits_table = $wpdb->prefix . 'spider_visits';
            
            $date_condition = '';
            switch ($period) {
                case 'today':
                    $date_condition = "DATE(visit_time) = CURDATE()";
                    break;
                case 'yesterday':
                    $date_condition = "DATE(visit_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)";
                    break;
            }
            
            $data = $wpdb->get_results($wpdb->prepare(
                "SELECT 
                    HOUR(visit_time) as hour,
                    spider_name,
                    COUNT(*) as visit_count
                FROM $visits_table 
                WHERE $date_condition AND is_ignored = 0
                GROUP BY HOUR(visit_time), spider_name
                ORDER BY hour ASC, visit_count DESC"
            ), ARRAY_A);
            
            // 按小时组织数据
            $hourly_details = array();
            for ($i = 0; $i < 24; $i++) {
                $hourly_details[$i] = array();
            }
            
            foreach ($data as $item) {
                $hourly_details[$item['hour']][] = array(
                    'name' => $item['spider_name'],
                    'count' => intval($item['visit_count'])
                );
            }
            
            return $hourly_details;
        }
        
        /**
         * 获取Top10蜘蛛数据
         */
        public function ajax_get_top_spiders() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            $period = sanitize_text_field($_POST['period'] ?? 'today');
            
            if (!in_array($period, array('today','yesterday'), true)) {
                $this->require_token('top_spiders', $period);
            }
            
            global $wpdb;
            $visits_table = $wpdb->prefix . 'spider_visits';
            
            $date_condition = '';
            switch ($period) {
                case 'today':
                    $date_condition = "DATE(visit_time) = CURDATE()";
                    break;
                case 'yesterday':
                    $date_condition = "DATE(visit_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)";
                    break;
                case 'week':
                    $date_condition = "DATE(visit_time) >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)";
                    break;
                case 'month':
                    $date_condition = "DATE(visit_time) >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)";
                    break;
            }
            
            // 获取总URL数用于计算百分比
            $total_urls = $wpdb->get_var($wpdb->prepare(
                "SELECT COUNT(*) FROM $visits_table WHERE $date_condition AND is_ignored = 0"
            ));
            
            $top_spiders = $wpdb->get_results($wpdb->prepare(
                "SELECT 
                    spider_name,
                    bot_type,
                    COUNT(*) as url_count,
                    ROUND(COUNT(*) * 100.0 / %d, 2) as percentage
                FROM $visits_table 
                WHERE $date_condition AND is_ignored = 0
                GROUP BY spider_name, bot_type
                ORDER BY url_count DESC
                LIMIT 10",
                $total_urls
            ), ARRAY_A);
            
            wp_send_json_success($top_spiders);
        }
        
        /**
         * 获取Top10爬取URL数据
         */
        public function ajax_get_top_urls() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            $period = sanitize_text_field($_POST['period'] ?? 'today');
            
            if (!in_array($period, array('today','yesterday'), true)) {
                $this->require_token('top_urls', $period);
            }
            
            global $wpdb;
            $visits_table = $wpdb->prefix . 'spider_visits';
            
            $date_condition = '';
            switch ($period) {
                case 'today':
                    $date_condition = "DATE(visit_time) = CURDATE()";
                    break;
                case 'yesterday':
                    $date_condition = "DATE(visit_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)";
                    break;
                case 'week':
                    $date_condition = "DATE(visit_time) >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)";
                    break;
                case 'month':
                    $date_condition = "DATE(visit_time) >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)";
                    break;
            }
            
            // 获取总访问数用于计算百分比
            $total_visits = $wpdb->get_var($wpdb->prepare(
                "SELECT COUNT(*) FROM $visits_table WHERE $date_condition AND is_ignored = 0"
            ));
            
            $top_urls = $wpdb->get_results($wpdb->prepare(
                "SELECT 
                    url,
                    url_type,
                    COUNT(*) as visit_count,
                    ROUND(COUNT(*) * 100.0 / %d, 2) as percentage
                FROM $visits_table 
                WHERE $date_condition AND is_ignored = 0
                GROUP BY url, url_type
                ORDER BY visit_count DESC
                LIMIT 10",
                $total_visits
            ), ARRAY_A);
            
            wp_send_json_success($top_urls);
        }
        
        /**
         * 获取Top10热门文章数据
         */
        public function ajax_get_top_articles() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            $period = sanitize_text_field($_POST['period'] ?? 'today');
            
            if (!in_array($period, array('today','yesterday'), true)) {
                $this->require_token('top_articles', $period);
            }
            
            global $wpdb;
            $visits_table = $wpdb->prefix . 'spider_visits';
            
            $date_condition = '';
            switch ($period) {
                case 'today':
                    $date_condition = "DATE(visit_time) = CURDATE()";
                    break;
                case 'yesterday':
                    $date_condition = "DATE(visit_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)";
                    break;
                case 'week':
                    $date_condition = "DATE(visit_time) >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)";
                    break;
                case 'month':
                    $date_condition = "DATE(visit_time) >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)";
                    break;
            }
            
            // 获取总文章访问数用于计算百分比
            $total_article_visits = $wpdb->get_var($wpdb->prepare(
                "SELECT COUNT(*) FROM $visits_table WHERE $date_condition AND is_ignored = 0 AND post_id > 0"
            ));
            
            $top_articles = $wpdb->get_results($wpdb->prepare(
                "SELECT 
                    post_id,
                    page_title as post_title,
                    url_type as post_type,
                    COUNT(*) as crawl_count,
                    ROUND(COUNT(*) * 100.0 / %d, 2) as percentage
                FROM $visits_table 
                WHERE $date_condition AND is_ignored = 0 AND post_id > 0
                GROUP BY post_id, page_title, url_type
                ORDER BY crawl_count DESC
                LIMIT 10",
                $total_article_visits
            ), ARRAY_A);
            
            wp_send_json_success($top_articles);
        }
        
        /**
         * 获取蜘蛛列表数据
         */
        public function ajax_get_spider_list() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            // 7天/30天为高级范围：必须令牌
            $period = sanitize_text_field($_POST['period'] ?? 'today');
            if (!in_array($period, array('today','yesterday'), true)) {
                $this->require_token('spider_list', $period);
            }
            // 保留 premium 信息用于前端提示
            $is_premium = $this->is_premium_version();
            $search = sanitize_text_field($_POST['search'] ?? '');
            $type = sanitize_text_field($_POST['type'] ?? '');
            
            global $wpdb;
            $visits_table = $wpdb->prefix . 'spider_visits';
            
            $date_condition = '';
            switch ($period) {
                case 'today':
                    $date_condition = "DATE(visit_time) = CURDATE()";
                    break;
                case 'yesterday':
                    $date_condition = "DATE(visit_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)";
                    break;
                case 'week':
                    $date_condition = "DATE(visit_time) >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)";
                    break;
                case 'month':
                    $date_condition = "DATE(visit_time) >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)";
                    break;
            }
            
            $where_conditions = array($date_condition);
            $where_values = array();
            
            if (!empty($search)) {
                $where_conditions[] = "spider_name LIKE %s";
                $where_values[] = '%' . $wpdb->esc_like($search) . '%';
            }
            
            if (!empty($type)) {
                $where_conditions[] = "bot_type = %s";
                $where_values[] = $type;
            }
            
            $where_clause = implode(' AND ', $where_conditions);
            
            // 获取总访问数用于计算百分比
            $total_visits = $wpdb->get_var($wpdb->prepare(
                "SELECT COUNT(*) FROM $visits_table WHERE $where_clause AND is_ignored = 0",
                $where_values
            ));
            
            $spiders = $wpdb->get_results($wpdb->prepare(
                "SELECT 
                    CONCAT(spider_name, '_', bot_type) as id,
                    spider_name,
                    bot_type,
                    COUNT(*) as url_count,
                    MAX(visit_time) as last_visit,
                    ROUND(COUNT(*) * 100.0 / %d, 2) as percentage,
                    CASE 
                        WHEN is_blocked = 1 THEN 'blocked'
                        WHEN is_ignored = 1 THEN 'ignored'
                        ELSE 'normal'
                    END as status,
                    CASE 
                        WHEN is_blocked = 1 THEN '已拦截'
                        WHEN is_ignored = 1 THEN '已忽略'
                        ELSE '正常'
                    END as status_text
                FROM $visits_table 
                WHERE $where_clause
                GROUP BY spider_name, bot_type, is_blocked, is_ignored
                ORDER BY url_count DESC
                LIMIT 50",
                array_merge(array($total_visits), $where_values)
            ), ARRAY_A);
            
            // 添加PRO版本提示信息
            $response_data = array(
                'spiders' => $spiders,
                'is_premium' => $is_premium,
                'premium_message' => $is_premium ? '' : '此功能需要激活PRO版本才能使用完整功能',
                'upgrade_url' => admin_url('admin.php?page=spider-license')
            );
            
            wp_send_json_success($response_data);
        }
        
        /**
         * 获取IP段数据
         */
        public function ajax_get_ip_segments() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            $period = sanitize_text_field($_POST['period'] ?? 'today');
            
            // 使用统一的安全许可证验证
            $verification = wp_spider_secure_license_verification();
            $access_result = $verification->verify_feature_access('ip_segments', $period);
            
            if (!$access_result['is_premium']) {
                wp_send_json_success($access_result);
                return;
            }
            $search = sanitize_text_field($_POST['search'] ?? '');
            
            global $wpdb;
            $visits_table = $wpdb->prefix . 'spider_visits';
            
            $date_condition = '';
            switch ($period) {
                case 'today':
                    $date_condition = "DATE(visit_time) = CURDATE()";
                    break;
                case 'yesterday':
                    $date_condition = "DATE(visit_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)";
                    break;
                case 'week':
                    $date_condition = "DATE(visit_time) >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)";
                    break;
                case 'month':
                    $date_condition = "DATE(visit_time) >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)";
                    break;
            }
            
            $where_conditions = array($date_condition);
            $where_values = array();
            
            if (!empty($search)) {
                $where_conditions[] = "ip_address LIKE %s";
                $where_values[] = '%' . $wpdb->esc_like($search) . '%';
            }
            
            $where_clause = implode(' AND ', $where_conditions);
            
            // 获取总访问数用于计算百分比
            $total_visits = $wpdb->get_var($wpdb->prepare(
                "SELECT COUNT(*) FROM $visits_table WHERE $where_clause AND is_ignored = 0",
                $where_values
            ));
            
            $ip_segments = $wpdb->get_results($wpdb->prepare(
                "SELECT 
                    CONCAT(spider_name, '_', SUBSTRING_INDEX(ip_address, '.', 3)) as id,
                    spider_name,
                    CONCAT(SUBSTRING_INDEX(ip_address, '.', 3), '.0/24') as ip_segment,
                    COUNT(*) as visit_count,
                    MAX(visit_time) as last_visit,
                    ROUND(COUNT(*) * 100.0 / %d, 2) as percentage
                FROM $visits_table 
                WHERE $where_clause AND is_ignored = 0
                GROUP BY spider_name, SUBSTRING_INDEX(ip_address, '.', 3)
                ORDER BY visit_count DESC
                LIMIT 50",
                array_merge(array($total_visits), $where_values)
            ), ARRAY_A);
            
            // 添加PRO版本提示信息
            $response_data = array(
                'segments' => $ip_segments
            );
            
            wp_send_json_success($response_data);
        }
        
        /**
         * 获取伪蜘蛛数据
         */
        public function ajax_get_fake_spiders() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            // 强制令牌：疑似伪蜘蛛属于付费功能
            $this->require_token('fake_spiders', 'general');
            $is_premium = true;
            
            $period = sanitize_text_field($_POST['period'] ?? 'today');
            
            global $wpdb;
            $visits_table = $wpdb->prefix . 'spider_visits';
            
            $date_condition = '';
            switch ($period) {
                case 'today':
                    $date_condition = "DATE(visit_time) = CURDATE()";
                    break;
                case 'yesterday':
                    $date_condition = "DATE(visit_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)";
                    break;
                case 'week':
                    $date_condition = "DATE(visit_time) >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)";
                    break;
                case 'month':
                    $date_condition = "DATE(visit_time) >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)";
                    break;
            }
            
            $fake_spiders = $wpdb->get_results($wpdb->prepare(
                "SELECT 
                    CONCAT(spider_name, '_', ip_address, '_', MD5(user_agent)) as id,
                    spider_name,
                    ip_address,
                    user_agent,
                    fake_reason,
                    COUNT(*) as visit_count
                FROM $visits_table 
                WHERE $date_condition AND is_fake_bot = 1
                GROUP BY spider_name, ip_address, user_agent, fake_reason
                ORDER BY visit_count DESC
                LIMIT 50"
            ), ARRAY_A);
            
            // 添加PRO版本提示信息
            $response_data = array(
                'fake_spiders' => $fake_spiders,
                'is_premium' => $is_premium,
                'premium_message' => $is_premium ? '' : '此功能需要激活PRO版本才能使用完整功能',
                'upgrade_url' => admin_url('admin.php?page=spider-license')
            );
            
            wp_send_json_success($response_data);
        }
        
        /**
         * 获取拦截规则数据
         */
        public function ajax_get_block_rules() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            // 强制令牌：蜘蛛拦截为付费功能
            $this->require_token('spider_blocking', 'general');
            $is_premium = true;
            
            $filter = sanitize_text_field($_POST['filter'] ?? '');
            
            global $wpdb;
            $block_table = $wpdb->prefix . 'spider_block_rules';
            
            $where_condition = '';
            if (!empty($filter)) {
                $where_condition = "WHERE block_type = %s";
            }
            
            $block_rules = $wpdb->get_results($wpdb->prepare(
                "SELECT 
                    id,
                    spider_name,
                    ip_address,
                    ip_range,
                    block_type,
                    is_active,
                    created_at
                FROM $block_table 
                $where_condition
                ORDER BY created_at DESC",
                !empty($filter) ? array($filter) : array()
            ), ARRAY_A);
            
            // 添加PRO版本提示信息
            $response_data = array(
                'rules' => $block_rules,
                'is_premium' => $is_premium,
                'premium_message' => $is_premium ? '' : '此功能需要激活PRO版本才能使用完整功能',
                'upgrade_url' => admin_url('admin.php?page=spider-license')
            );
            
            wp_send_json_success($response_data);
        }
        
        /**
         * 添加拦截规则
         */
        public function ajax_add_block_rule() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            // 令牌强校验
            $this->require_token('spider_blocking', 'general');
            
            $block_type = sanitize_text_field($_POST['block_type'] ?? '');
            $spider_name = sanitize_text_field($_POST['spider_name'] ?? '');
            $ip_address = sanitize_text_field($_POST['ip_address'] ?? '');
            $description = sanitize_textarea_field($_POST['description'] ?? '');
            
            if (empty($block_type)) {
                wp_send_json_error('拦截类型不能为空');
            }
            
            global $wpdb;
            $block_table = $wpdb->prefix . 'spider_block_rules';
            
            $insert_data = array(
                'block_type' => $block_type,
                'is_active' => 1,
                'created_at' => current_time('mysql')
            );
            
            if (!empty($spider_name)) {
                $insert_data['spider_name'] = $spider_name;
            }
            
            if (!empty($ip_address)) {
                if (strpos($ip_address, '/') !== false) {
                    $insert_data['ip_range'] = $ip_address;
                } else {
                    $insert_data['ip_address'] = $ip_address;
                }
            }
            
            $result = $wpdb->insert($block_table, $insert_data);
            
            if ($result === false) {
                wp_send_json_error('添加失败: ' . $wpdb->last_error);
            }
            
            wp_send_json_success('拦截规则添加成功');
        }
        
        /**
         * 删除拦截规则
         */
        public function ajax_remove_block_rule() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            // 令牌强校验
            $this->require_token('spider_blocking', 'general');
            
            $id = intval($_POST['id'] ?? 0);
            
            if (empty($id)) {
                wp_send_json_error('参数不完整');
            }
            
            global $wpdb;
            $block_table = $wpdb->prefix . 'spider_block_rules';
            
            $result = $wpdb->delete(
                $block_table,
                array('id' => $id),
                array('%d')
            );
            
            if ($result !== false) {
                wp_send_json_success('拦截规则删除成功');
            } else {
                wp_send_json_error('删除失败: ' . $wpdb->last_error);
            }
        }
        
        /**
         * 获取访问路径数据
         */
        public function ajax_get_access_paths() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            $period = sanitize_text_field($_POST['period'] ?? 'today');
            
            if (!in_array($period, array('today','yesterday'), true)) {
                $this->require_token('access_paths', $period);
            }
            
            $spider = sanitize_text_field($_POST['spider'] ?? '');
            $type = sanitize_text_field($_POST['type'] ?? '');
            $status = sanitize_text_field($_POST['status'] ?? '');
            $search = sanitize_text_field($_POST['search'] ?? '');
            $page = intval($_POST['page'] ?? 1);
            $per_page = intval($_POST['per_page'] ?? 20);
            
            global $wpdb;
            $visits_table = $wpdb->prefix . 'spider_visits';
            
            $date_condition = '';
            switch ($period) {
                case 'today':
                    $date_condition = "DATE(visit_time) = CURDATE()";
                    break;
                case 'yesterday':
                    $date_condition = "DATE(visit_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)";
                    break;
                case 'week':
                    $date_condition = "DATE(visit_time) >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)";
                    break;
                case 'month':
                    $date_condition = "DATE(visit_time) >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)";
                    break;
            }
            
            $where_conditions = array($date_condition);
            $where_values = array();
            
            if (!empty($spider)) {
                $where_conditions[] = "spider_name = %s";
                $where_values[] = $spider;
            }
            
            if (!empty($type)) {
                $where_conditions[] = "url_type = %s";
                $where_values[] = $type;
            }
            
            if (!empty($status)) {
                $where_conditions[] = "response_code = %d";
                $where_values[] = intval($status);
            }
            
            if (!empty($search)) {
                $where_conditions[] = "url LIKE %s";
                $where_values[] = '%' . $wpdb->esc_like($search) . '%';
            }
            
            $where_clause = implode(' AND ', $where_conditions);
            
            // 获取总访问数用于计算百分比
            $total_visits = $wpdb->get_var($wpdb->prepare(
                "SELECT COUNT(*) FROM $visits_table WHERE $where_clause AND is_ignored = 0",
                $where_values
            ));
            
            $offset = ($page - 1) * $per_page;
            
            $paths = $wpdb->get_results($wpdb->prepare(
                "SELECT 
                    url,
                    url_type,
                    spider_name,
                    COUNT(*) as visit_count,
                    ROUND(COUNT(*) * 100.0 / %d, 2) as percentage,
                    response_code,
                    AVG(response_time) as avg_response_time,
                    MAX(visit_time) as last_visit
                FROM $visits_table 
                WHERE $where_clause AND is_ignored = 0
                GROUP BY url, url_type, spider_name, response_code
                ORDER BY visit_count DESC
                LIMIT %d OFFSET %d",
                array_merge(array($total_visits), $where_values, array($per_page, $offset))
            ), ARRAY_A);
            
            // 获取总页数
            $total_count = $wpdb->get_var($wpdb->prepare(
                "SELECT COUNT(DISTINCT CONCAT(url, spider_name)) FROM $visits_table WHERE $where_clause AND is_ignored = 0",
                $where_values
            ));
            
            $total_pages = ceil($total_count / $per_page);
            
            wp_send_json_success(array(
                'paths' => $paths,
                'total_pages' => $total_pages,
                'current_page' => $page,
                'total_count' => $total_count
            ));
        }
        
        /**
         * 获取文章爬取数据
         */
        public function ajax_get_article_crawl() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            $period = sanitize_text_field($_POST['period'] ?? 'today');
            
            if (!in_array($period, array('today','yesterday'), true)) {
                $this->require_token('article_crawl', $period);
            }
            
            $spider = sanitize_text_field($_POST['spider'] ?? '');
            $type = sanitize_text_field($_POST['type'] ?? '');
            $status = sanitize_text_field($_POST['status'] ?? '');
            $search = sanitize_text_field($_POST['search'] ?? '');
            $page = intval($_POST['page'] ?? 1);
            $per_page = intval($_POST['per_page'] ?? 20);
            
            global $wpdb;
            $visits_table = $wpdb->prefix . 'spider_visits';
            
            $date_condition = '';
            switch ($period) {
                case 'today':
                    $date_condition = "DATE(visit_time) = CURDATE()";
                    break;
                case 'yesterday':
                    $date_condition = "DATE(visit_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)";
                    break;
                case 'week':
                    $date_condition = "DATE(visit_time) >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)";
                    break;
                case 'month':
                    $date_condition = "DATE(visit_time) >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)";
                    break;
            }
            
            $where_conditions = array($date_condition);
            $where_values = array();
            
            if (!empty($spider)) {
                $where_conditions[] = "spider_name = %s";
                $where_values[] = $spider;
            }
            
            if (!empty($type)) {
                $where_conditions[] = "url_type = %s";
                $where_values[] = $type;
            }
            
            if (!empty($status)) {
                if ($status === 'indexed') {
                    $where_conditions[] = "is_indexed = 1";
                } elseif ($status === 'not_indexed') {
                    $where_conditions[] = "is_indexed = 0";
                }
            }
            
            if (!empty($search)) {
                $where_conditions[] = "page_title LIKE %s";
                $where_values[] = '%' . $wpdb->esc_like($search) . '%';
            }
            
            $where_clause = implode(' AND ', $where_conditions);
            
            $offset = ($page - 1) * $per_page;
            
            // 调试：先检查是否有符合条件的数据
            $debug_query = "SELECT COUNT(*) as total, COUNT(DISTINCT post_id) as unique_posts FROM $visits_table WHERE is_ignored = 0 AND post_id > 0";
            $debug_count = $wpdb->get_row($debug_query, ARRAY_A);
            
            // 简化查询，先获取所有文章数据
            $articles = $wpdb->get_results($wpdb->prepare(
                "SELECT 
                    post_id,
                    page_title as post_title,
                    url_type as post_type,
                    url as post_url,
                    spider_name,
                    COUNT(*) as crawl_count,
                    MAX(visit_time) as last_crawl,
                    AVG(response_time) as avg_response_time,
                    is_indexed
                FROM $visits_table 
                WHERE is_ignored = 0 AND post_id IS NOT NULL AND post_id != 0
                GROUP BY post_id
                ORDER BY crawl_count DESC
                LIMIT %d OFFSET %d",
                array($per_page, $offset)
            ), ARRAY_A);
            
            // 获取总页数
            $total_count = $wpdb->get_var(
                "SELECT COUNT(DISTINCT post_id) FROM $visits_table WHERE is_ignored = 0 AND post_id IS NOT NULL AND post_id != 0"
            );
            
            $total_pages = ceil($total_count / $per_page);
            
            wp_send_json_success(array(
                'articles' => $articles,
                'total_pages' => $total_pages,
                'current_page' => $page,
                'total_count' => $total_count,
                'debug' => array(
                    'where_clause' => $where_clause,
                    'where_values' => $where_values,
                    'debug_count' => $debug_count,
                    'offset' => $offset,
                    'per_page' => $per_page,
                    'articles_count' => count($articles)
                )
            ));
        }
        
        /**
         * 获取路径统计数据
         */
        public function ajax_get_path_stats() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            $period = sanitize_text_field($_POST['period'] ?? 'today');
            
            if (!in_array($period, array('today','yesterday'), true)) {
                $this->require_token('path_stats', $period);
            }
            
            $spider = sanitize_text_field($_POST['spider'] ?? '');
            $type = sanitize_text_field($_POST['type'] ?? '');
            $status = sanitize_text_field($_POST['status'] ?? '');
            $search = sanitize_text_field($_POST['search'] ?? '');
            
            global $wpdb;
            $visits_table = $wpdb->prefix . 'spider_visits';
            
            $date_condition = '';
            switch ($period) {
                case 'today':
                    $date_condition = "DATE(visit_time) = CURDATE()";
                    break;
                case 'yesterday':
                    $date_condition = "DATE(visit_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)";
                    break;
                case 'week':
                    $date_condition = "DATE(visit_time) >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)";
                    break;
                case 'month':
                    $date_condition = "DATE(visit_time) >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)";
                    break;
            }
            
            $where_conditions = array($date_condition);
            $where_values = array();
            
            if (!empty($spider)) {
                $where_conditions[] = "spider_name = %s";
                $where_values[] = $spider;
            }
            
            if (!empty($type)) {
                $where_conditions[] = "url_type = %s";
                $where_values[] = $type;
            }
            
            if (!empty($status)) {
                $where_conditions[] = "response_code = %d";
                $where_values[] = intval($status);
            }
            
            if (!empty($search)) {
                $where_conditions[] = "url LIKE %s";
                $where_values[] = '%' . $wpdb->esc_like($search) . '%';
            }
            
            $where_clause = implode(' AND ', $where_conditions);
            
            $stats = $wpdb->get_row($wpdb->prepare(
                "SELECT 
                    COUNT(*) as total_paths,
                    COUNT(DISTINCT url) as unique_paths,
                    COUNT(DISTINCT spider_name) as active_spiders,
                    AVG(response_time) as avg_response_time
                FROM $visits_table 
                WHERE $where_clause AND is_ignored = 0",
                $where_values
            ), ARRAY_A);
            
            wp_send_json_success($stats);
        }
        
        /**
         * 获取URL类型统计数据
         */
        public function ajax_get_url_type_stats() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            $period = sanitize_text_field($_POST['period'] ?? 'today');
            $spider = sanitize_text_field($_POST['spider'] ?? '');
            $status = sanitize_text_field($_POST['status'] ?? '');
            
            global $wpdb;
            $visits_table = $wpdb->prefix . 'spider_visits';
            
            $date_condition = '';
            switch ($period) {
                case 'today':
                    $date_condition = "DATE(visit_time) = CURDATE()";
                    break;
                case 'yesterday':
                    $date_condition = "DATE(visit_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)";
                    break;
                case 'week':
                    $date_condition = "DATE(visit_time) >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)";
                    break;
                case 'month':
                    $date_condition = "DATE(visit_time) >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)";
                    break;
            }
            
            $where_conditions = array($date_condition);
            $where_values = array();
            
            if (!empty($spider)) {
                $where_conditions[] = "spider_name = %s";
                $where_values[] = $spider;
            }
            
            if (!empty($status)) {
                $where_conditions[] = "response_code = %d";
                $where_values[] = intval($status);
            }
            
            $where_clause = implode(' AND ', $where_conditions);
            
            $url_types = $wpdb->get_results($wpdb->prepare(
                "SELECT 
                    url_type,
                    COUNT(*) as count,
                    ROUND(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM $visits_table WHERE $where_clause AND is_ignored = 0), 2) as percentage
                FROM $visits_table 
                WHERE $where_clause AND is_ignored = 0
                GROUP BY url_type
                ORDER BY count DESC",
                $where_values
            ), ARRAY_A);
            
            wp_send_json_success($url_types);
        }
        
        /**
         * 安全验证AJAX处理
         */
        public function ajax_validate_premium_access() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            $feature = sanitize_text_field($_POST['feature'] ?? '');
            $period = sanitize_text_field($_POST['period'] ?? '');
            $token = sanitize_text_field($_POST['token'] ?? '');
            
            // 使用统一的安全许可证验证
            $verification = wp_spider_secure_license_verification();
            
            // 验证付费访问权限
            $access_result = $verification->verify_feature_access($feature, $period);
            
            // 生成安全响应
            $response = array(
                'is_premium' => $access_result['is_premium'],
                'feature' => $feature,
                'period' => $period,
                'timestamp' => time()
            );
            
            if (!$access_result['is_premium']) {
                $response['premium_message'] = $access_result['premium_message'];
                $response['upgrade_url'] = $access_result['upgrade_url'];
                $response['data'] = array();
            }
            
            wp_send_json_success($response);
        }
        
        /**
         * 令牌验证AJAX处理
         */
        public function ajax_verify_token() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            $token = sanitize_text_field($_POST['token'] ?? '');
            $feature = sanitize_text_field($_POST['feature'] ?? '');
            $period = sanitize_text_field($_POST['period'] ?? '');
            $client_hash = sanitize_text_field($_POST['client_hash'] ?? '');
            
            // 使用安全模块验证令牌（存在时），否则回退远程校验
            $is_valid = false;
            if (function_exists('wp_spider_premium_security')) {
                $security = wp_spider_premium_security();
                $is_valid = $security->validate_client_request($token, $feature, $period);
            } else if (function_exists('wp_spider_secure_license_verification')) {
                $verification = wp_spider_secure_license_verification();
                $res = $verification->verify_feature_access($feature, $period ?: 'general', null, $token);
                $is_valid = is_array($res) && !empty($res['success']);
            }
            
            // 验证客户端哈希
            $expected_hash = $security->generate_security_hash($feature, $period, $is_valid);
            $hash_valid = hash_equals($expected_hash, $client_hash);
            
            wp_send_json_success(array(
                'valid' => $is_valid && $hash_valid,
                'feature' => $feature,
                'period' => $period,
                'timestamp' => time()
            ));
        }
        
        /**
         * 许可证管理页面
         */
        public function license_page() {
            include plugin_dir_path(__FILE__) . 'templates/license-settings.php';
        }
        
        /**
         * 验证许可证密钥
         */
        public function validate_license_key($license_key) {
            // 首先验证许可证密钥格式
            if (strlen($license_key) < 10) {
                return false;
            }
            
            // 检查许可证密钥格式
            if (!preg_match('/^[A-Z0-9-]+$/', $license_key)) {
                return false;
            }
            
            // 使用安全许可证验证模块进行远程验证
            $verification = wp_spider_secure_license_verification();
            $result = $verification->verify_license($license_key);
            
            // 返回验证结果
            return $result['valid'] === true;
        }
        
        /**
         * 获取文章统计数据
         */
        public function ajax_get_article_stats() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            $period = sanitize_text_field($_POST['period'] ?? 'today');
            
            if (!in_array($period, array('today','yesterday'), true)) {
                $this->require_token('article_stats', $period);
            }
            
            $spider = sanitize_text_field($_POST['spider'] ?? '');
            $type = sanitize_text_field($_POST['type'] ?? '');
            $status = sanitize_text_field($_POST['status'] ?? '');
            $search = sanitize_text_field($_POST['search'] ?? '');
            
            global $wpdb;
            $visits_table = $wpdb->prefix . 'spider_visits';
            
            $date_condition = '';
            switch ($period) {
                case 'today':
                    $date_condition = "DATE(visit_time) = CURDATE()";
                    break;
                case 'yesterday':
                    $date_condition = "DATE(visit_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)";
                    break;
                case 'week':
                    $date_condition = "DATE(visit_time) >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)";
                    break;
                case 'month':
                    $date_condition = "DATE(visit_time) >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)";
                    break;
            }
            
            $where_conditions = array($date_condition);
            $where_values = array();
            
            if (!empty($spider)) {
                $where_conditions[] = "spider_name = %s";
                $where_values[] = $spider;
            }
            
            if (!empty($type)) {
                $where_conditions[] = "url_type = %s";
                $where_values[] = $type;
            }
            
            if (!empty($status)) {
                if ($status === 'indexed') {
                    $where_conditions[] = "is_indexed = 1";
                } elseif ($status === 'not_indexed') {
                    $where_conditions[] = "is_indexed = 0";
                }
            }
            
            if (!empty($search)) {
                $where_conditions[] = "page_title LIKE %s";
                $where_values[] = '%' . $wpdb->esc_like($search) . '%';
            }
            
            $where_clause = implode(' AND ', $where_conditions);
            
            // 先检查数据库中的实际数据结构
            $debug_sample = $wpdb->get_results(
                "SELECT post_id, page_title, url_type, is_indexed, is_ignored FROM $visits_table LIMIT 5",
                ARRAY_A
            );
            
            // 使用完整的WHERE条件进行查询
            $where_clause = implode(' AND ', $where_conditions);
            $where_clause .= " AND is_ignored = 0 AND post_id IS NOT NULL AND post_id != 0";
            
            $stats = $wpdb->get_row($wpdb->prepare(
                "SELECT 
                    COUNT(DISTINCT post_id) as total_articles,
                    COUNT(DISTINCT post_id) as crawled_articles,
                    COUNT(DISTINCT CASE WHEN is_indexed = 1 THEN post_id END) as indexed_articles,
                    AVG(1) as avg_links
                FROM $visits_table 
                WHERE $where_clause",
                $where_values
            ), ARRAY_A);
            
            // 调试：检查原始数据（使用相同的WHERE条件）
            $debug_query = "SELECT COUNT(*) as total, COUNT(DISTINCT post_id) as unique_posts, COUNT(CASE WHEN post_id > 0 THEN 1 END) as valid_posts FROM $visits_table WHERE $where_clause";
            $debug_stats = $wpdb->get_row($wpdb->prepare($debug_query, $where_values), ARRAY_A);
            
            // 确保返回正确的数据格式
            if ($stats) {
                $stats['debug'] = array(
                    'where_clause' => $where_clause,
                    'where_values' => $where_values,
                    'debug_stats' => $debug_stats,
                    'sample_data' => $debug_sample
                );
                wp_send_json_success($stats);
            } else {
                wp_send_json_success(array(
                    'total_articles' => 0,
                    'crawled_articles' => 0,
                    'indexed_articles' => 0,
                    'avg_links' => 0,
                    'debug' => array(
                        'where_clause' => $where_clause,
                        'where_values' => $where_values,
                        'debug_stats' => $debug_stats
                    )
                ));
            }
        }
        
        /**
         * 获取爬取趋势数据
         */
        public function ajax_get_crawl_trend() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            $period = sanitize_text_field($_POST['period'] ?? 'today');
            $spider = sanitize_text_field($_POST['spider'] ?? '');
            $type = sanitize_text_field($_POST['type'] ?? '');
            $metric = sanitize_text_field($_POST['metric'] ?? 'crawl_count');
            
            global $wpdb;
            $visits_table = $wpdb->prefix . 'spider_visits';
            
            $date_condition = '';
            switch ($period) {
                case 'today':
                    $date_condition = "DATE(visit_time) = CURDATE()";
                    break;
                case 'yesterday':
                    $date_condition = "DATE(visit_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)";
                    break;
                case 'week':
                    $date_condition = "DATE(visit_time) >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)";
                    break;
                case 'month':
                    $date_condition = "DATE(visit_time) >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)";
                    break;
            }
            
            $where_conditions = array($date_condition);
            $where_values = array();
            
            if (!empty($spider)) {
                $where_conditions[] = "spider_name = %s";
                $where_values[] = $spider;
            }
            
            if (!empty($type)) {
                $where_conditions[] = "url_type = %s";
                $where_values[] = $type;
            }
            
            $where_clause = implode(' AND ', $where_conditions);
            
            $trend_data = $wpdb->get_results(
                "SELECT 
                    DATE(visit_time) as date,
                    COUNT(*) as crawl_count,
                    AVG(response_time) as avg_response_time
                FROM $visits_table 
                WHERE is_ignored = 0 AND post_id IS NOT NULL AND post_id != 0
                GROUP BY DATE(visit_time)
                ORDER BY date ASC"
            , ARRAY_A);
            
            wp_send_json_success($trend_data);
        }
        
        /**
         * 批量操作处理
         */
        public function ajax_bulk_action() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            // 令牌强校验
            $this->require_token('spider_management', 'general');
            
            $type = sanitize_text_field($_POST['type'] ?? '');
            $action_name = sanitize_text_field($_POST['action_name'] ?? '');
            $ids = $_POST['ids'] ?? array();
            
            if (empty($type) || empty($action_name) || empty($ids)) {
                wp_send_json_error('参数不完整');
            }
            
            global $wpdb;
            $visits_table = $wpdb->prefix . 'spider_visits';
            
            $success_count = 0;
            foreach ($ids as $id) {
                $id = sanitize_text_field($id);
                
                switch ($action_name) {
                    case 'ignore':
                        $result = $wpdb->update(
                            $visits_table,
                            array('is_ignored' => 1),
                            array('spider_name' => $id),
                            array('%d'),
                            array('%s')
                        );
                        break;
                    case 'block':
                        $result = $wpdb->update(
                            $visits_table,
                            array('is_blocked' => 1),
                            array('spider_name' => $id),
                            array('%d'),
                            array('%s')
                        );
                        break;
                    case 'unignore':
                        $result = $wpdb->update(
                            $visits_table,
                            array('is_ignored' => 0),
                            array('spider_name' => $id),
                            array('%d'),
                            array('%s')
                        );
                        break;
                    case 'unblock':
                        $result = $wpdb->update(
                            $visits_table,
                            array('is_blocked' => 0),
                            array('spider_name' => $id),
                            array('%d'),
                            array('%s')
                        );
                        break;
                    default:
                        $result = false;
                }
                
                if ($result !== false) {
                    $success_count++;
                }
            }
            
            wp_send_json_success("成功处理 {$success_count} 条记录");
        }
        
        /**
         * 切换蜘蛛状态
         */
        public function ajax_toggle_spider_status() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            // 令牌强校验
            $this->require_token('spider_management', 'general');
            
            $id = sanitize_text_field($_POST['id'] ?? '');
            $status = sanitize_text_field($_POST['status'] ?? '');
            
            if (empty($id) || empty($status)) {
                wp_send_json_error('参数不完整');
            }
            
            global $wpdb;
            $visits_table = $wpdb->prefix . 'spider_visits';
            
            // 兼容前端传入的复合ID（例如：Googlebot_search_engine）
            $spider_name = $id;
            $bot_type = null;
            if (strpos($id, '_') !== false) {
                list($spider_name, $bot_type) = explode('_', $id, 2);
            }
            
            // 根据目标状态同时维护忽略/拦截两个字段
            $update_data = array(
                'is_ignored' => 0,
                'is_blocked' => 0,
            );
            if ($status === 'ignored') {
                $update_data['is_ignored'] = 1;
            } elseif ($status === 'blocked') {
                $update_data['is_blocked'] = 1;
            }
            
            // 根据是否包含 bot_type 选择不同的 where 条件
            if (!empty($bot_type)) {
                $result = $wpdb->update(
                    $visits_table,
                    $update_data,
                    array('spider_name' => $spider_name, 'bot_type' => $bot_type),
                    array('%d','%d'),
                    array('%s','%s')
                );
            } else {
                $result = $wpdb->update(
                    $visits_table,
                    $update_data,
                    array('spider_name' => $spider_name),
                    array('%d','%d'),
                    array('%s')
                );
            }
            
            if ($result !== false) {
                wp_send_json_success('状态更新成功');
            } else {
                wp_send_json_error('状态更新失败');
            }
        }
        
        /**
         * 拦截IP段
         */
        public function ajax_block_ip_segment() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            // 令牌强校验
            $this->require_token('spider_blocking', 'general');
            
            $id = sanitize_text_field($_POST['id'] ?? '');
            
            if (empty($id)) {
                wp_send_json_error('参数不完整');
            }
            
            // 这里可以添加IP段拦截逻辑
            wp_send_json_success('IP段拦截成功');
        }
        
        /**
         * 拦截伪蜘蛛
         */
        public function ajax_block_fake_spider() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            // 令牌强校验
            $this->require_token('spider_blocking', 'general');
            
            $id = sanitize_text_field($_POST['id'] ?? '');
            
            if (empty($id)) {
                wp_send_json_error('参数不完整');
            }
            
            // 这里可以添加伪蜘蛛拦截逻辑
            wp_send_json_success('伪蜘蛛拦截成功');
        }
        
        /**
         * 切换规则状态
         */
        public function ajax_toggle_rule_status() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            // 令牌强校验
            $this->require_token('link_rules', 'general');
            
            $id = intval($_POST['id'] ?? 0);
            $is_active = intval($_POST['is_active'] ?? 0);
            
            if (empty($id)) {
                wp_send_json_error('参数不完整');
            }
            
            global $wpdb;
            $rules_table = $wpdb->prefix . 'spider_link_rules';
            
            $result = $wpdb->update(
                $rules_table,
                array('is_enabled' => $is_active),
                array('id' => $id),
                array('%d'),
                array('%d')
            );
            
            if ($result !== false) {
                wp_send_json_success('规则状态更新成功');
            } else {
                wp_send_json_error('规则状态更新失败');
            }
        }
        
        /**
         * 删除规则
         */
        public function ajax_delete_rule() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            // 令牌强校验
            $this->require_token('link_rules', 'general');
            
            $id = intval($_POST['id'] ?? 0);
            
            if (empty($id)) {
                wp_send_json_error('参数不完整');
            }
            
            global $wpdb;
            $rules_table = $wpdb->prefix . 'spider_link_rules';
            
            $result = $wpdb->delete(
                $rules_table,
                array('id' => $id),
                array('%d')
            );
            
            if ($result !== false) {
                wp_send_json_success('规则删除成功');
            } else {
                wp_send_json_error('规则删除失败');
            }
        }
        
        // ==================== SPA主页面 ====================
        
        /**
         * SPA仪表板页面
         */
        public function spa_dashboard_page() {
            if (!current_user_can('manage_options')) {
                wp_die('权限不足');
            }
            
            // 包含SPA仪表板模板
            include plugin_dir_path(__FILE__) . 'templates/spa-dashboard.php';
        }
        
        /**
         * SPA主页面
         */
        public function spa_main_page() {
            if (!current_user_can('manage_options')) {
                wp_die('权限不足');
            }
            
            // 包含SPA主页面模板
            include plugin_dir_path(__FILE__) . 'templates/spa-main.php';
        }
        
        /**
         * SPA测试页面
         */
        public function spa_test_page() {
            if (!current_user_can('manage_options')) {
                wp_die('权限不足');
            }
            
            // 包含SPA测试页面模板
            include plugin_dir_path(__FILE__) . 'templates/spa-test.php';
        }
        
        /**
         * 简单SPA测试页面
         */
        public function simple_spa_test_page() {
            if (!current_user_can('manage_options')) {
                wp_die('权限不足');
            }
            
            // 包含简单SPA测试页面模板
            include plugin_dir_path(__FILE__) . 'templates/simple-spa-test.php';
        }
        
        // ==================== SPA页面AJAX处理函数 ====================
        
        /**
         * 获取蜘蛛概况页面内容
         */
        public function ajax_get_overview_page() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            ob_start();
            include plugin_dir_path(__FILE__) . 'templates/spider-overview.php';
            $content = ob_get_clean();
            
            wp_send_json_success(array(
                'content' => $content,
                'title' => '蜘蛛概况'
            ));
        }
        
        /**
         * 获取蜘蛛日志页面内容
         */
        public function ajax_get_logs_page() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            ob_start();
            include plugin_dir_path(__FILE__) . 'templates/spider-list.php';
            $content = ob_get_clean();
            
            wp_send_json_success(array(
                'content' => $content,
                'title' => '蜘蛛日志'
            ));
        }
        
        /**
         * 获取蜘蛛列表页面内容
         */
        public function ajax_get_list_page() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            ob_start();
            include plugin_dir_path(__FILE__) . 'templates/spider-list.php';
            $content = ob_get_clean();
            
            wp_send_json_success(array(
                'content' => $content,
                'title' => '蜘蛛列表'
            ));
        }
        
        /**
         * 获取访问路径页面内容
         */
        public function ajax_get_paths_page() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            ob_start();
            include plugin_dir_path(__FILE__) . 'templates/access-paths.php';
            $content = ob_get_clean();
            
            wp_send_json_success(array(
                'content' => $content,
                'title' => '访问路径'
            ));
        }
        
        /**
         * 获取文章爬取页面内容
         */
        public function ajax_get_articles_page() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            ob_start();
            include plugin_dir_path(__FILE__) . 'templates/article-crawl.php';
            $content = ob_get_clean();
            
            wp_send_json_success(array(
                'content' => $content,
                'title' => '文章爬取'
            ));
        }
        
        /**
         * 获取收录分析页面内容
         */
        public function ajax_get_indexing_page() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            ob_start();
            include plugin_dir_path(__FILE__) . 'templates/indexing-page.php';
            $content = ob_get_clean();
            
            wp_send_json_success(array(
                'content' => $content,
                'title' => '收录分析'
            ));
        }

        /**
         * 手动收录检测：优先第三方接口，失败时回退搜索页特征检测
         */
        // 兼容旧钩子：spider_check_indexing 与 spider_check_indexing_status 都指向此实现
        public function ajax_check_indexing_status() { return $this->ajax_check_indexing_status_v2(); }

        public function ajax_check_indexing_status_v2() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            if (!current_user_can('manage_options')) { wp_send_json_error('权限不足'); }

            $url = sanitize_text_field($_POST['url'] ?? '');
            $engine = sanitize_text_field($_POST['engine'] ?? 'google');
            if (!filter_var($url, FILTER_VALIDATE_URL)) { wp_send_json_error('无效URL'); }

            // 1) 第三方接口优先（需在设置里配置）
            $third = $this->check_indexing_via_thirdparty($engine, $url);
            if ($third && isset($third['status'])) {
                $this->save_indexing_record($url, $engine, $third['status'], $third['http_status'] ?? null);
                wp_send_json_success(array_merge(array('engine' => $engine), $third));
            }

            // 2) 回退：搜索结果页特征检测（笨方法）
            $fallback = $this->check_indexing_via_searchpage($engine, $url);
            $this->save_indexing_record($url, $engine, $fallback['status'], $fallback['http_status'] ?? null);
            wp_send_json_success(array_merge(array('engine' => $engine), $fallback));
        }

        private function check_indexing_via_thirdparty($engine, $url) {
            // 读取可选的第三方接口配置（存于 wp_options）
            $conf = get_option('wp_spider_thirdparty_indexing', array());
            $engineConf = isset($conf[$engine]) ? (array)$conf[$engine] : array();
            $apiUrl = $engineConf['api_url'] ?? '';
            if (empty($apiUrl)) { return null; }

            $params = array(
                'url' => $url,
                'engine' => $engine,
                'token' => $engineConf['token'] ?? '',
                'apikey' => $engineConf['apikey'] ?? ''
            );
            $resp = wp_remote_post($apiUrl, array(
                'timeout' => 12,
                'headers' => array('Content-Type' => 'application/x-www-form-urlencoded', 'User-Agent' => 'Spider-Monitor-IndexCheck'),
                'body' => http_build_query($params),
                'sslverify' => false
            ));
            if (is_wp_error($resp)) { return null; }
            $code = wp_remote_retrieve_response_code($resp);
            $body = trim(wp_remote_retrieve_body($resp));
            $data = json_decode($body, true);
            if ($code === 200 && is_array($data)) {
                // 约定第三方返回 { indexed: bool, http_status?: number }
                if (isset($data['indexed'])) {
                    return array(
                        'status' => $data['indexed'] ? 'indexed' : 'not_indexed',
                        'http_status' => isset($data['http_status']) ? intval($data['http_status']) : null,
                        'source' => 'thirdparty'
                    );
                }
            }
            return null;
        }

        private function check_indexing_via_searchpage($engine, $url) {
            // 简单规则：访问搜索页并判断是否出现该URL（仅作参考）
            $queryUrl = '';
            $encoded = urlencode($url);
            switch ($engine) {
                case 'baidu':
                    $queryUrl = 'https://www.baidu.com/s?wd=' . $encoded;
                    break;
                case 'bing':
                    $queryUrl = 'https://www.bing.com/search?q=' . $encoded;
                    break;
                case '360':
                    $queryUrl = 'https://www.so.com/s?q=' . $encoded;
                    break;
                case 'sogou':
                    $queryUrl = 'https://www.sogou.com/web?query=' . $encoded;
                    break;
                default:
                    $queryUrl = 'https://www.google.com/search?q=' . $encoded;
            }
            $resp = wp_remote_get($queryUrl, array(
                'timeout' => 12,
                'headers' => array(
                    'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36',
                    'Accept-Language' => 'zh-CN,zh;q=0.9,en;q=0.8'
                ),
                'sslverify' => false
            ));
            $ok = false; $httpStatus = 0;
            if (!is_wp_error($resp)) {
                $httpStatus = wp_remote_retrieve_response_code($resp);
                $body = wp_remote_retrieve_body($resp);
                // 简单包含判断（防止编码差异，去掉协议与尾部斜杠）
                $normalized = preg_replace('#^https?://#','', rtrim($url,'/'));
                $ok = (stripos($body, $normalized) !== false);
            }
            return array(
                'status' => $ok ? 'indexed_probable' : 'not_indexed',
                'http_status' => $httpStatus,
                'source' => 'searchpage'
            );
        }

        private function save_indexing_record($url, $engine, $status, $httpStatus = null) {
            global $wpdb;
            $table = $wpdb->prefix . 'spider_indexing_status';
            // 创建表（一次性，避免缺表）
            $wpdb->query("CREATE TABLE IF NOT EXISTS $table (
                id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
                url TEXT NOT NULL,
                engine_type VARCHAR(20) NOT NULL,
                status VARCHAR(32) NOT NULL,
                http_status INT NULL,
                last_spider_visit DATETIME NULL,
                last_checked DATETIME NOT NULL,
                KEY engine_type (engine_type)
            ) DEFAULT CHARSET=utf8mb4;");

            $wpdb->insert($table, array(
                'url' => $url,
                'engine_type' => $engine,
                'status' => $status,
                'http_status' => $httpStatus,
                'last_spider_visit' => null,
                'last_checked' => current_time('mysql')
            ));
        }
        
        /**
         * 获取搜索引擎推送页面内容
         */
        public function ajax_get_push_page() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            ob_start();
            include plugin_dir_path(__FILE__) . 'templates/push-page.php';
            $content = ob_get_clean();
            
            wp_send_json_success(array(
                'content' => $content,
                'title' => '搜索引擎推送'
            ));
        }
        
        /**
         * 获取设置页面内容
         */
        public function ajax_get_settings_page() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            ob_start();
            include plugin_dir_path(__FILE__) . 'templates/settings-hub.php';
            $content = ob_get_clean();
            
            wp_send_json_success(array(
                'content' => $content,
                'title' => '设置'
            ));
        }
        
        /**
         * 获取插件设置页面内容
         */
        public function ajax_get_plugin_settings_page() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            ob_start();
            include plugin_dir_path(__FILE__) . 'templates/settings-page.php';
            $content = ob_get_clean();
            
            wp_send_json_success(array(
                'content' => $content,
                'title' => '插件设置'
            ));
        }
        
        /**
         * 获取设置标签页内容
         */
        public function ajax_get_settings_tab() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            $tab = sanitize_text_field($_POST['tab'] ?? 'records');
            
            // 定义模板映射
            $template_map = array(
                'rules'   => plugin_dir_path(__FILE__) . 'templates/rules-page.php',
                'pro'     => plugin_dir_path(__FILE__) . 'templates/pro-page.php'
            );
            
            $template = $template_map[$tab] ?? $template_map['rules'];
            
            if (!file_exists($template)) {
                wp_send_json_error('模板文件不存在: ' . $template);
            }
            
            ob_start();
            include $template;
            $content = ob_get_clean();
            
            wp_send_json_success(array(
                'content' => $content,
                'title' => ucfirst($tab) . ' 设置'
            ));
        }
        
        /**
         * 获取许可证页面内容
         */
        public function ajax_get_license_page() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            if (!current_user_can('manage_options')) {
                wp_send_json_error('权限不足');
            }
            
            ob_start();
            include plugin_dir_path(__FILE__) . 'templates/license-settings.php';
            $content = ob_get_clean();
            
            wp_send_json_success(array(
                'content' => $content,
                'title' => '许可证管理'
            ));
        }
        
        /**
         * 渲染许可证管理页面
         */
        public function render_license_page() {
            if (!current_user_can('manage_options')) {
                wp_die('权限不足');
            }
            
            include plugin_dir_path(__FILE__) . 'templates/license-settings.php';
        }

        private function require_token($feature, $period = null) {
            require_once plugin_dir_path(__FILE__) . 'includes/remote-auth.php';
            $res = WP_Spider_Remote_Auth::enforce_token($feature, $period);
            if (!is_array($res) || empty($res['success'])) {
                wp_send_json_error(array(
                    'message' => isset($res['message']) ? $res['message'] : '访问令牌无效或已过期',
                    'upgrade_url' => admin_url('admin.php?page=spider-license')
                ));
            }
            return isset($res['token']) ? $res['token'] : null;
        }
        
        /**
         * 处理广告点击统计
         */
        public function handle_ad_click_tracking() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            $ad_id = sanitize_text_field($_POST['ad_id'] ?? '');
            if (empty($ad_id)) {
                wp_send_json_error('广告ID不能为空');
            }
            
            // 记录广告点击统计
            $this->track_ad_click($ad_id);
            
            wp_send_json_success('统计记录成功');
        }
        
        /**
         * 记录广告点击
         */
        private function track_ad_click($ad_id) {
            global $wpdb;
            
            $table_name = $wpdb->prefix . 'spider_ad_clicks';
            
            // 确保表存在
            $this->create_ad_tracking_table();
            
            $wpdb->insert(
                $table_name,
                array(
                    'ad_id' => $ad_id,
                    'user_ip' => $this->get_user_ip(),
                    'user_agent' => sanitize_text_field($_SERVER['HTTP_USER_AGENT'] ?? ''),
                    'clicked_at' => current_time('mysql'),
                    'page_url' => sanitize_url($_SERVER['HTTP_REFERER'] ?? '')
                ),
                array('%s', '%s', '%s', '%s', '%s')
            );
        }
        
        /**
         * 创建广告统计表
         */
        private function create_ad_tracking_table() {
            global $wpdb;
            
            $table_name = $wpdb->prefix . 'spider_ad_clicks';
            
            $charset_collate = $wpdb->get_charset_collate();
            
            $sql = "CREATE TABLE IF NOT EXISTS $table_name (
                id mediumint(9) NOT NULL AUTO_INCREMENT,
                ad_id varchar(50) NOT NULL,
                user_ip varchar(45) NOT NULL,
                user_agent text,
                clicked_at datetime DEFAULT CURRENT_TIMESTAMP,
                page_url varchar(255),
                PRIMARY KEY (id),
                KEY ad_id (ad_id),
                KEY clicked_at (clicked_at)
            ) $charset_collate;";
            
            require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
            dbDelta($sql);
        }
        
        /**
         * 获取用户IP地址
         */
        private function get_user_ip() {
            $ip_keys = array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR');
            foreach ($ip_keys as $key) {
                if (array_key_exists($key, $_SERVER) === true) {
                    foreach (explode(',', $_SERVER[$key]) as $ip) {
                        $ip = trim($ip);
                        if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false) {
                            return $ip;
                        }
                    }
                }
            }
            return $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
        }
        
        /**
         * 获取广告数据API
         */
        public function get_ads_data() {
            check_ajax_referer('wp_spider_monitor_nonce', 'nonce');
            
            // 从数据库或外部API获取广告数据
            $ads = $this->fetch_ads_from_source();
            
            wp_send_json_success($ads);
        }
        
        /**
         * 从数据源获取广告
         */
        private function fetch_ads_from_source() {
            // 这里可以从数据库、外部API或其他数据源获取广告
            // 目前返回示例数据
            return array(
                array(
                    'id' => 'ad-1',
                    'title' => 'WordPress优化服务',
                    'description' => '专业WordPress网站优化',
                    'image' => 'https://via.placeholder.com/200x100/0073aa/ffffff?text=WordPress+优化',
                    'link' => 'https://zibovip.top',
                    'target' => '_blank',
                    'active' => true
                ),
                array(
                    'id' => 'ad-2',
                    'title' => 'SEO工具推荐',
                    'description' => '提升网站搜索排名',
                    'image' => 'https://via.placeholder.com/200x100/28a745/ffffff?text=SEO+工具',
                    'link' => 'https://zibovip.top',
                    'target' => '_blank',
                    'active' => true
                )
            );
        }
        
        /**
         * 添加底部标志到插件页面
         */
        public function add_footer_logo() {
            // 只在蜘蛛监控相关页面显示
            $current_screen = get_current_screen();
            if ($current_screen && strpos($current_screen->id, 'spider') !== false) {
                echo '<div class="spider-footer">';
                echo '<div class="spider-footer-content">';
                echo '<a href="https://zibovip.top" target="_blank" class="spider-footer-logo">';
                echo '<span class="logo-text">小Z</span>';
                echo '</a>';
                echo '</div>';
                echo '</div>';
            }
        }
    }

    // 全局辅助函数：在模板中统一判断是否为高级版本
    if (!function_exists('wp_spider_is_premium')) {
        function wp_spider_is_premium() {
            return (bool) apply_filters('wp_spider_monitor_is_premium', false);
        }
    }

    // 分析器类


    // 注册激活和停用钩子
    register_activation_hook(__FILE__, function() {
        $spider_monitor = new WP_Spider_Monitor();
        $spider_monitor->activate();
    });

    register_deactivation_hook(__FILE__, function() {
        $spider_monitor = new WP_Spider_Monitor();
        $spider_monitor->deactivate();
    });

    // 初始化插件
    $GLOBALS['wp_spider_monitor'] = new WP_Spider_Monitor();
